9.1 KiB
Troubleshooting
Authentication Errors
AuthenticationError: Invalid or missing API key
The server rejected your API key.
Causes and fixes:
- Key not set — pass
apiKeyto the constructor or useprocess.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
\ror\nand throwsSecurityErrorbefore the request is sent. Regenerate the key.
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:
baseUrlis correct — the default ishttps://api.nomyo.ai(port 12435).- You have network access to the host.
- TLS is not being blocked by a proxy or firewall.
SecurityError: HTTPS is required
You passed an http:// URL without setting allowHttp: true.
// 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:
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:
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.
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:
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.allbatches. - Add client-side throttling (see Rate Limits).
- Increase
maxRetriesso the client backs off longer before giving up:
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:
// 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 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: trueoutput). - 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:
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:
npm update nomyo-js
DisposedError: Method called after dispose()
You called a method on a client that has already been disposed.
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).
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:
// 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):
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
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
import { getMemoryProtectionInfo } from 'nomyo-js';
console.log(getMemoryProtectionInfo());
Inspect response metadata
The _metadata field in every response carries server-side diagnostics:
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:
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();