Skip to main content

Common errors and how to fix them

Messages below are quoted from the packages. Values in <angle brackets> (and example slugs, keys, and hosts) vary with your project.

Definition errors (at import time)

defineIntegration() throws one error listing every problem, each prefixed with the path that failed:
ekanos validate reports the same problems as definition.schema or definition.load findings.

Slug is not kebab-case

Fix: Use lowercase [a-z0-9] segments separated by single hyphens:

Unrecognized key

When an unrecognized key is among the failures, the error ends with this reminder:
Cause: The schema is strict everywhere. Either you declared a host-assigned field, or you have a typo in a key name. Fix: Remove the host-assigned fields listed above, and move per-tool effect/sensitivity into proposes.tools. If you are confident the key is valid, your project’s @ekanos/integration-schema may be newer than your CLI — run ekanos upgrade --check.

Widget id is invalid or duplicated

Fix: Use kebab-case, prefixed with your slug:

Tool name is not snake_case

Fix:

Webhook, schedule, or action name is not kebab-case

Action names (the keys of actions) follow the same rule:
Fix:
Vendor event names like payment_intent.succeeded are never valid ids — map them to a kebab-case id and put the vendor’s name in description.

Cron expression is invalid

Cause: Cron has strict numeric bounds: minute 0-59, hour 0-23, day-of-month 1-31, month 1-12, day-of-week 0-7. Names (MON), macros (@daily), and a seconds field are not supported. Fix:
See Schedules for the full cron rules.

OAuth endpoint is not covered by egress

The same message appears for oauth.provider.tokenUrl. Fix: Add the origin of both endpoints:

Storage key is invalid

A key is "<dataType>" or "<dataType>/<subtype>". Two different messages can fire:
Cause: The part before the / must be an allowed data type for its scope: activation, settings, metrics_summary, sync_state, or cache under storage.account; config, preferences, or cache under storage.user. secret is reserved — use ctx.secrets instead. Fix:

Validation findings (ekanos validate)

ekanos validate exits 3 (validation) when there is at least one error-severity finding. Warnings alone do not fail it.

project.host-compiler-rules (warning)

Cause: The host gate’s checks/typecheck-host-rules pass compiles under strict and noUncheckedIndexedAccess. validate warns; ekanos publish escalates this finding to an error and refuses to submit. Fix: Add to tsconfig.json:

project.slug-agreement (error)

Fix: Change one to match the other:

collision.widget-id (error)

Cause: Two integrations in the same ekanos.json declare the same widget id. Tool names collide the same way (collision.tool-name), compared by their slug-prefixed effective names. Fix: Prefix with your integration slug:

icons/pro-only (warning)

Cause: The generated harness loads Font Awesome Free only. Fix: Pick a Free icon name. When a Free equivalent is known, the finding’s hint names it (Use "fa-<alternative>" instead — the nearest Free equivalent.).

Runtime errors

Cannot find module @ekanos/sdk

Cause: Dependencies are not installed. Fix: Run pnpm install (or your package manager’s equivalent) after scaffolding.

StorageValidationError

ctx.storage throws StorageValidationError (code: 'STORAGE_VALIDATION_FAILED', with scope, key, and hint) when you access an undeclared key, write a value that fails the key’s schema, or read stored data that no longer matches the schema. Fix for schema changes: Schema evolution is manual. Never loosen a schema in place — add a new key or widen with a union:
When adding a field to an existing schema, make it .optional() — a required field throws on every row written before the change.

EgressDeniedError

Cause: A handler called ctx.fetch for an origin not covered by egress (redirect targets included). The error has code: 'EGRESS_DENIED' and an origin property. On the host, an allowlisted name that resolves to a private, loopback, or link-local address is also refused, with a reason. Fix: Add the origin to egress:
Then validate and republish.

SecretAccessError

Cause: ctx.secrets.set() targeted a name that exists only in an admin-issued (source or global) tier. The error has code: 'SECRET_ACCESS_DENIED'. Fix: Only write account-tier secrets — for example, OAuth tokens stored from onTokens. In tests, createMockContext({ secrets: { account: { … }, admin: { … } } }) reproduces the split.

NoRecordedResponseError (harness fixtures mode)

The message continues with the exact fixture line to paste. The console also logs a line such as [harness:<slug>] refused GET https://api.acme.example/payments. Cause: The harness is in fixtures mode and the request has no matching fixture for the active variant. It was refused, not sent. Fix: Record the fixture in harness.config.ts:
Or add a live block to the entry and switch the toolbar to Live API.

No IntegrationActivationProvider is mounted

Cause: useActivateIntegration() / useDeactivateIntegration() reject with this message at call time when no provider is mounted. Fix: The host and the dev harness both mount the provider. If you render an activation form in isolation (a test or Storybook), mount it yourself:

ctx.storage.user throws for machine actors

The SDK’s mock context throws:
Cause: ctx.storage.user needs a user. A machine actor (ctx.actor.kind === 'machine') has none. Fix: Use account-scoped storage for anything a machine actor — such as a workflow — can reach:

CLI errors (ekanos publish, ekanos status, …)

In JSON mode, errors arrive as { ok: false, error: { code, message, hint } }. The exit code and code always pair up.

Exit 4: auth_required

Hint: Run "ekanos login --host https://your-ekanos-host". Other auth_required messages cover an expired or revoked session (for example, The stored session for https://your-ekanos-host is no longer valid.) and a pending MFA requirement. Fix:

Exit 5: forbidden

The hint lists your actual seats, for example: You hold a seat on: my-source (developer). Run "ekanos use <slug>" with one of these. Cause: ekanos use or ekanos publish targeted a source you hold no seat on. Fix:

Exit 9: precondition_failed (schema skew)

Cause: Your project resolves a newer @ekanos/integration-schema than the CLI bundles. validate and publish fail before loading your definition. Fix:
Or pin the CLI by hand with npm i -D @ekanos/cli@latest, then re-run.

Exit 10: gate_failed

ekanos publish refuses before submitting when the local findings pass has errors:
ekanos status --watch exits 10 when the host gate rejects the submitted version:
Fix: Read the findings (in data.findings, or with ekanos status --findings), fix them, bump the version, and publish again. Common gate failures:
  • TypeScript errors under the host’s stricter rules (checks/typecheck-host-rules)
  • Test failures (checks/tests)

Still stuck?

  1. Read the hint — every CLI error carries an imperative hint
  2. Run with --json — ekanos validate --json gives the full findings list
  3. Test locally — ekanos test before publishing
Email npm@govastly.com with:
  • The exact error message
  • Your ekanos.json and the relevant section of src/integration.ts
  • The output of ekanos validate --json