nomyo-js/doc/troubleshooting.md
2026-04-16 16:44:26 +02:00

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 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.
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.

// 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.all batches.
  • Add client-side throttling (see Rate Limits).
  • Increase maxRetries so 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: 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:

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