# 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(); ```