evanw/esbuild · error · Error
Must specify "kind" when calling "resolve"
Error message
Must specify "kind" when calling "resolve"
What it means
The plugin `resolve()` helper (lib/shared/common.ts:1268) requires a `kind` option that tells esbuild what kind of import is being resolved (e.g. `'import-statement'`, `'entry-point'`, `'require-call'`). The code reads `kind` with `mustBeString` and, if it is null/undefined, throws this error before sending the resolve request to the service.
Solutions
- Always pass a `kind` string matching one of the documented ResolveKind values (e.g. `'import-statement'`, `'entry-point'`, `'require-call'`, `'dynamic-import'`).
- Inside an onResolve hook, propagate the incoming `args.kind` so the value matches the real import context.
Example fix
// before
const r = await build.resolve('./foo');
// after
const r = await build.resolve('./foo', { kind: 'import-statement' }); Defensive patterns
Strategy: validation
Validate before calling
const RESOLVE_KINDS = ['entry-point','import-statement','require-call','dynamic-import','require-resolve','import-rule','url-token'];
function assertKind(kind: any) {
if (typeof kind !== 'string' || !RESOLVE_KINDS.includes(kind)) throw new Error('Invalid/missing resolve kind');
} Type guard
function isValidResolveKind(k: any): k is string {
return typeof k === 'string' && ['entry-point','import-statement','require-call','dynamic-import','require-resolve','import-rule','url-token'].includes(k);
} Prevention
- Forward args.kind from onResolve handlers when re-resolving.
- Keep a constant list of valid kinds near your plugin code.
When it happens
Trigger: Calling `build.resolve(path)` or `build.resolve(path, {})` without a `kind` field inside a plugin callback.
Common situations: Assuming `kind` has a default; porting code from a different resolver API; passing `kind` as part of a nested object instead of the options top level.
Related errors
- Cannot call "resolve" before plugin setup has completed
- onLoad() call is missing a filter
- onResolve() call is missing a filter
- Plugin at index must be an object
- Expected onEnd() callback in plugin
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/4357dea1952cb2c0.
Report an issue: GitHub.
Appendix: source
Thrown at lib/shared/common.ts:1268
let resolveDir = getFlag(options, keys, 'resolveDir', mustBeString)
let kind = getFlag(options, keys, 'kind', mustBeString)
let pluginData = getFlag(options, keys, 'pluginData', canBeAnything)
let importAttributes = getFlag(options, keys, 'with', mustBeObject)
checkForInvalidFlags(options, keys, 'in resolve() call')
return new Promise((resolve, reject) => {
const request: protocol.ResolveRequest = {
command: 'resolve',
path,
key: buildKey,
pluginName: name,
}
if (pluginName != null) request.pluginName = pluginName
if (importer != null) request.importer = importer
if (namespace != null) request.namespace = namespace
if (resolveDir != null) request.resolveDir = resolveDir
if (kind != null) request.kind = kind
else throw new Error(`Must specify "kind" when calling "resolve"`)
if (pluginData != null) request.pluginData = details.store(pluginData)
if (importAttributes != null) request.with = sanitizeStringMap(importAttributes, 'with')
sendRequest<protocol.ResolveRequest, protocol.ResolveResponse>(refs, request, (error, response) => {
if (error !== null) reject(new Error(error))
else resolve({
errors: replaceDetailsInMessages(response!.errors, details),
warnings: replaceDetailsInMessages(response!.warnings, details),
path: response!.path,
external: response!.external,
sideEffects: response!.sideEffects,
namespace: response!.namespace,
suffix: response!.suffix,
pluginData: details.load(response!.pluginData),
})
})
})
}View on GitHub (pinned to f6058f8364)