{"record":{"id":"f95a676285732e04","repo":"ramensoftware/windhawk","slug":"mod-id-must-be-specified-in-the-source-code","errorCode":null,"errorMessage":"Mod id must be specified in the source code","messagePattern":"Mod id must be specified in the source code","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/windhawk-vscode/src/extension.ts","lineNumber":832,"sourceCode":"\t\t\t\tsucceeded\n\t\t\t});\n\t\t},\n\t\tinstallMod: async message => {\n\t\t\tconst data: InstallModData = message.data;\n\n\t\t\tlet installedModDetails: InstallModReplyData['installedModDetails'] = null;\n\t\t\tlet readBackError: WireError | undefined;\n\n\t\t\ttry {\n\t\t\t\twindhawkCompilerOutput?.clear();\n\t\t\t\twindhawkCompilerOutput?.hide();\n\n\t\t\t\tconst modId = data.modId;\n\t\t\t\tconst modSource = data.modSource;\n\n\t\t\t\tconst metadata = await extractMetadataOrThrow(this._utils.core, modSource, this._language);\n\t\t\t\tif (!metadata.id) {\n\t\t\t\t\tthrow new Error('Mod id must be specified in the source code');\n\t\t\t\t} else if (metadata.id !== modId) {\n\t\t\t\t\tthrow new Error('Mod id specified in the source code doesn\\'t match');\n\t\t\t\t}\n\n\t\t\t\tconst op = this._utils.core.installMod({\n\t\t\t\t\tstorageId: modId,\n\t\t\t\t\tsource: modSource,\n\t\t\t\t\tmetadata,\n\t\t\t\t\tdisabled: data.disabled,\n\t\t\t\t\tloggingEnabled: data.loggingEnabled,\n\t\t\t\t\tcompileLocally: this._alwaysCompileModsLocally,\n\t\t\t\t\ttrackInProfile: true,\n\t\t\t\t});\n\n\t\t\t\t// Track the operation for the duration of the install so\n\t\t\t\t// cancelInstallMod can find it, and drop it however it settles -\n\t\t\t\t// a completion, a failure, or the cancel itself.\n\t\t\t\tthis._currentInstallOps.set(modId, op);","sourceCodeStart":814,"sourceCodeEnd":850,"githubUrl":"https://github.com/ramensoftware/windhawk/blob/61d99ed8e182e1af1b60109612b6763ad1b4b74e/src/windhawk-vscode/src/extension.ts#L814-L850","documentation":"When installing a mod from source, the panel extracts the mod's metadata (which includes the `id` from the source's metadata block) and requires it to be present before installMod is called. A mod source without an `#pragma`-style id / metadata id cannot be identified in storage, so the operation aborts.","triggerScenarios":"WindhawkPanel handles an install message where data.modSource's extracted metadata has no id — e.g. installing from a hand-written or pasted source file missing the id field.","commonSituations":"Author creates a new mod and forgets the id line in the metadata block; a tool strips metadata comments; pasting only the code portion of a mod.","solutions":["Add the `id` field to the mod's metadata block in the source (e.g. `// ==WindhawkMod== ... ** id=... `)","Re-download the complete mod source including its metadata header","Fix whatever preprocessing stripped the metadata before extraction"],"exampleFix":"// before\n// ==WindhawkMod==\n// ==/WindhawkMod==\n// after\n// ==WindhawkMod==\n// ... ==/WindhawkMod==\n/*\n[Metadata]\nid=my.mod.id\n*/","handlingStrategy":"validation","validationCode":"const meta = parseModMetadata(modSource);\nif (!meta?.id) {\n  alert('Mod source is missing the required id metadata field.');\n  return;\n}","typeGuard":"const hasId = (m: { id?: string } | null): m is { id: string } => typeof m?.id === 'string' && m.id.length > 0;","tryCatchPattern":"try { await panel.installMod(data); } catch (e) { if (e.message === 'Mod id must be specified in the source code') notifyMissingId(); else throw e; }","preventionTips":["Use a mod template that includes the id metadata line","Never strip metadata comments when copying mod source","Validate metadata (id present) before submitting an install request"],"tags":["metadata","validation","mod-install"],"backgroundTag":"missing-required-argument","analyzedSha":"61d99ed8e182e1af1b60109612b6763ad1b4b74e","analyzedAt":"2026-09-12T14:02:41.115Z","contentChangedAt":"2026-09-12T14:02:41.115Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}