fix: base_url
doc: created
This commit is contained in:
parent
6e02559f4e
commit
43165f86f2
17 changed files with 2151 additions and 293 deletions
314
doc/troubleshooting.md
Normal file
314
doc/troubleshooting.md
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
# Troubleshooting
|
||||
|
||||
## Authentication Errors
|
||||
|
||||
### `AuthenticationError: Invalid or missing API key`
|
||||
|
||||
The server rejected your API key.
|
||||
|
||||
**Causes and fixes:**
|
||||
|
||||
- Key not set — pass `apiKey` to the constructor or use `process.env.NOMYO_API_KEY`.
|
||||
- Key has leading/trailing whitespace — check the value with `console.log(JSON.stringify(process.env.NOMYO_API_KEY))`.
|
||||
- Key contains CR or LF characters — the client rejects keys with `\r` or `\n` and throws `SecurityError` before the request is sent. Regenerate the key.
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
apiKey: process.env.NOMYO_API_KEY, // never hardcode
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Connection Errors
|
||||
|
||||
### `APIConnectionError: Network error` / `connect ECONNREFUSED`
|
||||
|
||||
The client could not reach the router.
|
||||
|
||||
**Check:**
|
||||
|
||||
1. `baseUrl` is correct — the default is `https://api.nomyo.ai` (port **12435**).
|
||||
2. You have network access to the host.
|
||||
3. TLS is not being blocked by a proxy or firewall.
|
||||
|
||||
### `SecurityError: HTTPS is required`
|
||||
|
||||
You passed an `http://` URL without setting `allowHttp: true`.
|
||||
|
||||
```javascript
|
||||
// Local dev only
|
||||
const client = new SecureChatCompletion({
|
||||
baseUrl: 'http://localhost:12435',
|
||||
allowHttp: true,
|
||||
});
|
||||
```
|
||||
|
||||
Never set `allowHttp: true` in production — the server public key fetch and all request data would travel unencrypted.
|
||||
|
||||
### `APIConnectionError: Request timed out`
|
||||
|
||||
The default timeout is 60 seconds. Larger models or busy endpoints may need more:
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
apiKey: process.env.NOMYO_API_KEY,
|
||||
timeout: 120000, // 2 minutes
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Loading Failures
|
||||
|
||||
### `Error: Failed to load keys: no such file or directory`
|
||||
|
||||
The `keyDir` directory or the PEM files inside it don't exist. On first run the library generates and saves a new key pair automatically. If you specified a custom `keyDir`, make sure the directory is writable:
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
apiKey: process.env.NOMYO_API_KEY,
|
||||
keyDir: '/var/lib/myapp/nomyo-keys', // directory must exist and be writable
|
||||
});
|
||||
```
|
||||
|
||||
### `Error: Invalid passphrase` / `Error: Failed to decrypt private key`
|
||||
|
||||
The password you passed to `loadKeys()` or `keyRotationPassword` doesn't match what was used to encrypt the file.
|
||||
|
||||
```javascript
|
||||
await client.loadKeys(
|
||||
'client_keys/private_key.pem',
|
||||
'client_keys/public_key.pem',
|
||||
process.env.NOMYO_KEY_PASSWORD, // must match the password used on generateKeys()
|
||||
);
|
||||
```
|
||||
|
||||
### `Error: RSA key too small`
|
||||
|
||||
The library enforces a minimum key size of 2048 bits. If you have old 1024-bit keys, regenerate them:
|
||||
|
||||
```javascript
|
||||
await client.generateKeys({
|
||||
saveToFile: true,
|
||||
keyDir: 'client_keys',
|
||||
keySize: 4096, // recommended
|
||||
});
|
||||
```
|
||||
|
||||
### `Error: Failed to load keys` (browser)
|
||||
|
||||
Key loading from files is a Node.js-only feature. In browsers, keys are generated in memory on first use. Do not call `loadKeys()` in a browser context.
|
||||
|
||||
---
|
||||
|
||||
## Rate Limit Errors
|
||||
|
||||
### `RateLimitError: Rate limit exceeded`
|
||||
|
||||
All automatic retries were exhausted. The default limit is 2 requests/second; burst allows 4 requests/second once per 10-second window.
|
||||
|
||||
**Fixes:**
|
||||
|
||||
- Reduce concurrency — avoid large `Promise.all` batches.
|
||||
- Add client-side throttling (see [Rate Limits](rate-limits.md)).
|
||||
- Increase `maxRetries` so the client backs off longer before giving up:
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
apiKey: process.env.NOMYO_API_KEY,
|
||||
maxRetries: 5,
|
||||
});
|
||||
```
|
||||
|
||||
### `ServiceUnavailableError` with 30-minute cool-down
|
||||
|
||||
Burst limits were hit repeatedly and a cool-down was applied to your key. Wait 30 minutes, then review your request patterns.
|
||||
|
||||
---
|
||||
|
||||
## Model / Tier Errors
|
||||
|
||||
### `ForbiddenError: Model not allowed for this security tier`
|
||||
|
||||
The model you requested is not available at the security tier you specified. Try a lower tier or a different model:
|
||||
|
||||
```javascript
|
||||
// If 'maximum' tier rejects the model, try 'high' or 'standard'
|
||||
const response = await client.create({
|
||||
model: 'Qwen/Qwen3.5-27B',
|
||||
messages: [...],
|
||||
security_tier: 'high', // try 'standard' if still rejected
|
||||
});
|
||||
```
|
||||
|
||||
See [Models — Security Tier Compatibility](models.md#security-tier-compatibility) for details.
|
||||
|
||||
---
|
||||
|
||||
## Crypto / Security Errors
|
||||
|
||||
### `SecurityError: Decryption failed`
|
||||
|
||||
The response could not be decrypted. This is intentionally vague to avoid leaking crypto details.
|
||||
|
||||
**Possible causes:**
|
||||
|
||||
- The server returned a malformed response (check `debug: true` output).
|
||||
- A network proxy modified the response body.
|
||||
- The server's public key changed mid-session — the next request will re-fetch it automatically.
|
||||
|
||||
Enable debug mode to log the raw response and narrow the cause:
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
apiKey: process.env.NOMYO_API_KEY,
|
||||
debug: true,
|
||||
});
|
||||
```
|
||||
|
||||
### `Error: Unsupported protocol version` / `Error: Unsupported encryption algorithm`
|
||||
|
||||
The server sent a response in a protocol version or with an encryption algorithm not supported by this client version. Update the package:
|
||||
|
||||
```bash
|
||||
npm update nomyo-js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `DisposedError`: Method called after `dispose()`
|
||||
|
||||
You called a method on a client that has already been disposed.
|
||||
|
||||
```javascript
|
||||
client.dispose();
|
||||
await client.create(...); // throws DisposedError
|
||||
```
|
||||
|
||||
Create a new client instance if you need to make more requests after disposal.
|
||||
|
||||
---
|
||||
|
||||
## Memory Protection Warnings
|
||||
|
||||
### `getMemoryProtectionInfo()` returns `method: 'zero-only'`
|
||||
|
||||
This is normal for a pure JavaScript installation. The library zeroes sensitive buffers immediately after use but cannot lock pages to prevent swapping (OS `mlock` requires a native addon).
|
||||
|
||||
```javascript
|
||||
import { getMemoryProtectionInfo } from 'nomyo-js';
|
||||
|
||||
const info = getMemoryProtectionInfo();
|
||||
// { method: 'zero-only', canLock: false, isPlatformSecure: false }
|
||||
```
|
||||
|
||||
For environments where swap-file exposure is unacceptable (HIPAA PHI, classified data), install the optional `nomyo-native` addon or run on a system with swap disabled.
|
||||
|
||||
---
|
||||
|
||||
## Node.js-Specific Issues
|
||||
|
||||
### `ReferenceError: crypto is not defined`
|
||||
|
||||
In CommonJS modules on Node.js before v19, `crypto` is not a global. Import it explicitly:
|
||||
|
||||
```javascript
|
||||
// CommonJS
|
||||
const { webcrypto } = require('crypto');
|
||||
global.crypto = webcrypto;
|
||||
|
||||
// Or switch to ES modules (recommended)
|
||||
// package.json: "type": "module"
|
||||
```
|
||||
|
||||
The library itself imports `crypto` correctly — this error only appears if your own application code tries to use `crypto` directly.
|
||||
|
||||
### `SyntaxError: Cannot use import statement in a module` / CommonJS vs ESM
|
||||
|
||||
The package ships both CommonJS (`dist/node/`) and ESM (`dist/esm/`) builds. Node.js selects the correct one automatically via `package.json` `exports`. If you see import errors, check that your `package.json` or bundler is not forcing the wrong format.
|
||||
|
||||
For ESM: set `"type": "module"` in your `package.json` or use `.mjs` file extensions.
|
||||
For CommonJS: use `require('nomyo-js')` or `.cjs` extensions.
|
||||
|
||||
### TypeScript: `Cannot find module 'nomyo-js'` / missing types
|
||||
|
||||
Ensure your `tsconfig.json` includes `"moduleResolution": "bundler"` or `"moduleResolution": "node16"` and that `nomyo-js` is in `dependencies` (not just `devDependencies`):
|
||||
|
||||
```bash
|
||||
npm install nomyo-js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Browser-Specific Issues
|
||||
|
||||
### `Content Security Policy blocked`
|
||||
|
||||
If your app's CSP restricts `script-src` or `connect-src`, add the NOMYO API domain:
|
||||
|
||||
```
|
||||
Content-Security-Policy: connect-src https://api.nomyo.ai;
|
||||
```
|
||||
|
||||
### `TypeError: Failed to fetch` (CORS)
|
||||
|
||||
The NOMYO API includes CORS headers. If you see CORS errors in a browser, verify the `baseUrl` is correct (HTTPS, correct port) and that no browser extension is blocking the request.
|
||||
|
||||
### Keys not persisted across page reloads
|
||||
|
||||
This is expected behaviour — browsers do not have file system access. Keys are generated fresh on each page load. If you need persistent keys in a browser context, implement your own `loadKeys`/`generateKeys` wrapper using `localStorage` or `IndexedDB` (not recommended for high-security scenarios).
|
||||
|
||||
---
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
### Enable verbose logging
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
apiKey: process.env.NOMYO_API_KEY,
|
||||
debug: true,
|
||||
});
|
||||
```
|
||||
|
||||
Debug mode logs: key generation/loading, server public key fetches, request encryption details, retry attempts, and response decryption.
|
||||
|
||||
### Check memory protection status
|
||||
|
||||
```javascript
|
||||
import { getMemoryProtectionInfo } from 'nomyo-js';
|
||||
console.log(getMemoryProtectionInfo());
|
||||
```
|
||||
|
||||
### Inspect response metadata
|
||||
|
||||
The `_metadata` field in every response carries server-side diagnostics:
|
||||
|
||||
```javascript
|
||||
const response = await client.create({ ... });
|
||||
console.log(response._metadata);
|
||||
// {
|
||||
// payload_id: '...',
|
||||
// is_encrypted: true,
|
||||
// encryption_algorithm: 'hybrid-aes256-rsa4096',
|
||||
// security_tier: 'standard',
|
||||
// memory_protection: { ... },
|
||||
// }
|
||||
```
|
||||
|
||||
### Test with minimum configuration
|
||||
|
||||
Strip all optional configuration and test with the simplest possible call to isolate the issue:
|
||||
|
||||
```javascript
|
||||
import { SecureChatCompletion } from 'nomyo-js';
|
||||
|
||||
const client = new SecureChatCompletion({ apiKey: process.env.NOMYO_API_KEY });
|
||||
const r = await client.create({
|
||||
model: 'Qwen/Qwen3-0.6B',
|
||||
messages: [{ role: 'user', content: 'ping' }],
|
||||
});
|
||||
console.log(r.choices[0].message.content);
|
||||
client.dispose();
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue