ramensoftware/windhawk · error
Failed to parse mod metadata
Error message
Failed to parse mod metadata
What it means
extractMetadataOrThrow wraps core.parseModSource for handlers that need metadata or nothing: if the parsed result has no metadata it throws, preferring the core's own metadata error string and falling back to this generic message. It reproduces the throw-on-parse-failure behavior modSource.extractMetadata previously had.
Solutions
- Open the mod source and confirm the // ==WindhawkMod== ... // ==/WindhawkMod== header block exists and is well-formed.
- Fix the syntax/metadata errors listed in parsed.errors (the thrown message may already carry the core's specific error).
- Ensure the correct language argument is passed to parseModSource for the file.
- Validate the metadata block with a known-good mod as a template before re-running the operation.
Example fix
// before (broken mod source) // ==WindhawkMod== //@id my.mod // ==/WindhawkMod== <- missing name, parse fails // after // ==WindhawkMod== //@id my.mod //@name My Mod // ==/WindhawkMod==
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check before calling handlers that need metadata
const src = fs.readFileSync(modPath, 'utf8');
if (!src.includes('==WindhawkMod==') || !src.includes('==/WindhawkMod==')) {
throw new Error(`${modPath}: missing ==WindhawkMod== metadata block`);
} Type guard
function hasMetadata(parsed: { metadata?: ModMetadata | null }): parsed is { metadata: ModMetadata } {
return parsed.metadata != null;
} Try / catch
try {
const meta = await extractMetadataOrThrow(core, modSource, 'text/x-c++src');
} catch (e) {
if (e.message.includes('Failed to parse mod metadata') || e.message.includes('metadata')) {
openModAndHighlightMetadataBlock();
} else { throw e; }
} Prevention
- Always include a complete, well-formed // ==WindhawkMod== header block; start from a template mod.
- Lint the metadata block (ids, name, description fields) as a pre-save step in tooling.
- Pass the correct language identifier to parseModSource for the file type.
- Treat edits to the metadata block as high-risk and re-validate after every change.
When it happens
Trigger: Any handler (e.g. build, metadata display, mod install prep) calls extractMetadataOrThrow with mod source that clang-format/parse cannot yield metadata from: a syntax error in the .windhawk mod source, missing // ==WindhawkMod== header block, malformed metadata fields, or wrong language passed to parseModSource.
Common situations: A mod file is missing the ==WindhawkMod== metadata block or has a typo in it (e.g. ==WindhawkMod== with wrong casing/spacing); a partially written mod being edited mid-save; a file that is C++ source but submitted with the wrong language id.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Mod id must be specified in the source code
- Missing settings key
- Initial settings arrays must contain at least one template…
- Invalid object array schema definition.
- Unknown setting type for value
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/c0602662cfdc96a7.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk-vscode/src/extension.ts:2083
}
// Surface each failed parseModSource section as its own error notification,
// leaving the other sections' parsing unaffected.
function reportModSourceParseErrors(parsed: ParsedModSource) {
for (const error of [parsed.errors.metadata, parsed.errors.readme, parsed.errors.initialSettings]) {
if (error !== undefined) {
reportException(new Error(error));
}
}
}
// Metadata-or-throw convenience over parseModSource for the handlers that
// previously called modSource.extractMetadata directly (which threw on any
// parse failure).
async function extractMetadataOrThrow(core: WindhawkCore, modSource: string, language: string): Promise<ModMetadata> {
const parsed = await core.parseModSource(modSource, language);
if (!parsed.metadata) {
throw new Error(parsed.errors.metadata ?? 'Failed to parse mod metadata');
}
return parsed.metadata;
}
// Surface the clang warnings a successful local compile still produced. Append
// them to the compiler-output channel and return whether anything was written,
// so the caller can decide whether to reveal the channel (without stealing
// focus). A clean compile or a precompiled download carries no warnings, so this
// is a no-op there.
function appendCompilerWarnings(warnings: string | undefined): boolean {
if (!warnings) {
return false;
}
windhawkCompilerOutput?.append(warnings + '\n');
return true;
}
function reportCompilerException(e: any, treatCompilationErrorAsException = false) {View on GitHub (pinned to 61d99ed8e1)