Skip to Content
ErrorsNEXUS_INVALID_TOKEN

This page documents the 0.4 release candidates of @nexusdi/core. The newest on npm is 0.4.0-rc.1. The documentation for 0.3.2, the current release, is at nexus.js.org. Try the release candidate.

NEXUS_INVALID_TOKEN

NEXUS_INVALID_TOKEN means a value used as a token is not a class or a token (Token or MultiToken), or a Token was created without a description. new Token('') throws it at once, get() and resolve() throw it for a value that is no token, and Nexus.create reports it inside NEXUS_BLUEPRINT_INVALID for a providers entry whose token is not a token. validate() reports it the same way for a bad deps entry. A bad entry in the deps of a provider raises NEXUS_INVALID_PROVIDER with the reason bad-dep.

Reproduce NEXUS_INVALID_TOKEN

The region creates a Token with an empty description. No container exists yet, so core writes the full text itself, and the message is the same with or without errors().

import { Token, isNexusError } from '@nexusdi/core'; interface IReactorCore { readonly output: number; } let caught: unknown; try { new Token<IReactorCore>(''); } catch (error) { caught = error; } const line = isNexusError(caught) ? caught.message : null; // -> '[NEXUS_INVALID_TOKEN] the string "" is not a token description. A Token needs a non-empty description string.' console.log(line);

Try it: save the region as error.ts and run npx tsx error.ts. It prints one line that says the empty string is not a token description. Then run the second region, which passes a 0.3 symbol token to get(). It registers errors(), so it prints the full text: the symbol Symbol(ReactorCore) is not a token, and a token is a class or a token (Token or MultiToken).

import { Nexus, Token, isNexusError, provide } from '@nexusdi/core'; import { errors } from '@nexusdi/errors'; interface IReactorCore { readonly output: number; } const REACTOR = new Token<IReactorCore>('ReactorCore'); class FusionReactor implements IReactorCore { readonly output = 1.21; } await using ship = await Nexus.create( [provide(REACTOR, { useClass: FusionReactor })], { plugins: [errors()] }, ); // A 0.3 symbol token, which TypeScript would reject without the cast. const legacy = Symbol.for('ReactorCore') as never; let caught: unknown; try { ship.get(legacy); } catch (error) { caught = error; } const text = isNexusError(caught) ? caught.message : null; // -> '[NEXUS_INVALID_TOKEN] the symbol Symbol(ReactorCore) is not a token. A token is a class, a Token or a MultiToken.' console.log(text);

Then save the fix region below as fixed.ts and run npx tsx fixed.ts. It prints 1.21.

Fix NEXUS_INVALID_TOKEN

NEXUS_INVALID_TOKEN is fixed by naming every dependency with a class or a token (Token or MultiToken), and by giving each Token a non-empty description. The description is the name that errors and graph() show. A 0.3 symbol token becomes new Token<T>(description).

import { Nexus, Token, provide } from '@nexusdi/core'; interface IReactorCore { readonly output: number; } const REACTOR = new Token<IReactorCore>('ReactorCore'); class FusionReactor implements IReactorCore { readonly output = 1.21; } await using ship = await Nexus.create([ provide(REACTOR, { useClass: FusionReactor }), ]); const output = ship.get(REACTOR).output; // -> 1.21 console.log(output);

Fields of InvalidTokenError

InvalidTokenError carries these fields:

  • received: a description of the value, such as the symbol Symbol(ReactorCore).
  • entry: the deps entry of resolve() or validate() this error is about, or null.
  • module: the module whose providers holds the value, or null outside compilation.
  • index: the index of that providers entry, or null outside compilation.
  • reason: bad-description, not-a-deps-value, bad-modifier, bare-multi-token, alias-target, or null for a value that is none of the token kinds.
  • detail: the values the reason names.
  • otherCopy: true when another copy of @nexusdi/core made the value.