{"id":"4357dea1952cb2c0","repo":"evanw/esbuild","slug":"must-specify-kind-when-calling-resolve","errorCode":null,"errorMessage":"Must specify \"kind\" when calling \"resolve\"","messagePattern":"Must specify \"kind\" when calling \"resolve\"","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/shared/common.ts","lineNumber":1264,"sourceCode":"        let resolveDir = getFlag(options, keys, 'resolveDir', mustBeString)\n        let kind = getFlag(options, keys, 'kind', mustBeString)\n        let pluginData = getFlag(options, keys, 'pluginData', canBeAnything)\n        let importAttributes = getFlag(options, keys, 'with', mustBeObject)\n        checkForInvalidFlags(options, keys, 'in resolve() call')\n\n        return new Promise((resolve, reject) => {\n          const request: protocol.ResolveRequest = {\n            command: 'resolve',\n            path,\n            key: buildKey,\n            pluginName: name,\n          }\n          if (pluginName != null) request.pluginName = pluginName\n          if (importer != null) request.importer = importer\n          if (namespace != null) request.namespace = namespace\n          if (resolveDir != null) request.resolveDir = resolveDir\n          if (kind != null) request.kind = kind\n          else throw new Error(`Must specify \"kind\" when calling \"resolve\"`)\n          if (pluginData != null) request.pluginData = details.store(pluginData)\n          if (importAttributes != null) request.with = sanitizeStringMap(importAttributes, 'with')\n\n          sendRequest<protocol.ResolveRequest, protocol.ResolveResponse>(refs, request, (error, response) => {\n            if (error !== null) reject(new Error(error))\n            else resolve({\n              errors: replaceDetailsInMessages(response!.errors, details),\n              warnings: replaceDetailsInMessages(response!.warnings, details),\n              path: response!.path,\n              external: response!.external,\n              sideEffects: response!.sideEffects,\n              namespace: response!.namespace,\n              suffix: response!.suffix,\n              pluginData: details.load(response!.pluginData),\n            })\n          })\n        })\n      }","sourceCodeStart":1246,"sourceCodeEnd":1282,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/lib/shared/common.ts#L1246-L1282","documentation":"Inside a plugin, build.resolve(path, options) forwards to esbuild's resolver; the 'kind' option tells it the import context (import-statement, entry-point, require-resolve, etc.) because resolution rules differ by kind (e.g. ESM vs CJS). At lib/shared/common.ts:1264 esbuild throws if 'kind' is omitted, since guessing would silently pick the wrong resolution semantics and produce wrong external/path results.","triggerScenarios":"Calling build.resolve('./foo') with no options. Calling build.resolve('./foo', { importer }) forgetting kind. Passing kind: undefined explicitly.","commonSituations":"Plugin does custom resolution and copies a partial options object. Refactor that drops the kind field. Devs reading the type signature ResolveOptions and assuming kind is optional (it's optional in the type but required at runtime for this codepath).","solutions":["Always pass kind: one of 'entry-point' | 'import-statement' | 'require-call' | 'dynamic-import' | 'require-resolve' | 'css-rule' | 'css-at-rule' | 'js-url' | 'css-url' | 'css-import' | 'json-import'.","Match the kind to how the import appears in source: import x from → 'import-statement', require() → 'require-call'.","Add a TS helper that asserts kind is present: type ResolveKind = ...; and a runtime check."],"exampleFix":"// before\nconst r = await build.resolve('./mod', { importer: file });\n// after\nconst r = await build.resolve('./mod', { importer: file, kind: 'import-statement' });","handlingStrategy":"validation","validationCode":"const RESOLVE_KINDS = new Set([\n  'entry-point','import-statement','require-call','dynamic-import',\n  'require-resolve','css-rule','css-at-rule','css-url','css-import',\n  'js-url','json-import',\n]);\nfunction safeResolve(build, path, opts) {\n  if (!opts?.kind || !RESOLVE_KINDS.has(opts.kind)) {\n    throw new TypeError('build.resolve requires opts.kind from the supported set');\n  }\n  return build.resolve(path, opts);\n}","typeGuard":"function isResolveKind(v): v is import('esbuild').ResolveKind {\n  return typeof v === 'string' && [\n    'entry-point','import-statement','require-call','dynamic-import',\n    'require-resolve','css-rule','css-at-rule','css-url','css-import',\n    'js-url','json-import',\n  ].includes(v);\n}","tryCatchPattern":null,"preventionTips":["Always pass kind when calling build.resolve; match it to the import syntax in source.","Write a small helper that asserts kind to centralise the rule.","Keep the kind set in sync with the installed esbuild version's types."],"tags":["plugins","resolve","validation"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}