LykosAI/StabilityMatrix · error · InvalidOperationException
Expected closing parenthesis.
Error message
Expected closing parenthesis.
What it means
Thrown by ParseParenthesized when the token that should terminate a weighted group reaches the closing-token check but is not literally the ')' character, even though its scopes matched 'punctuation.definition.array.end.prompt' or 'meta.structure.weight.prompt'. The parser verifies the actual substring text, not just scopes, before consuming the closer.
Solutions
- Use a matching ')' to close the parenthesized group
- Check the tokenizer/grammar (textmate) version matches what PromptSyntaxBuilder expects for scope names
- Verify the prompt has balanced, same-type brackets: '(a:1.1)' not '(a:1.1]'
- Catch InvalidOperationException and log the offending prompt string for diagnosis
Example fix
// before var prompt = "(sharp focus:1.2]"; // after var prompt = "(sharp focus:1.2)";
Defensive patterns
Strategy: try-catch
Validate before calling
bool UsesMatchingBrackets(string prompt) => !prompt.Contains("]") && !prompt.Contains("}") || prompt.Count(c => c=='(') == prompt.Count(c => c==')'); Type guard
null
Try / catch
try { var node = builder.Parse(prompt); } catch (InvalidOperationException ex) when (ex.Message.Contains("closing parenthesis")) { // log prompt and tokenizer scope info; report bracket mismatch } Prevention
- Use only '(' to close weighted groups, never ']' or '}'
- Keep the tokenizer/textmate grammar version aligned with the parser
- Sanitize prompts containing mixed bracket styles before parsing
- Log the failing prompt text to diagnose grammar mismatches
When it happens
Trigger: A token whose scopes claim an end punctuation but whose text is not ')' — e.g. a tokenizer/grammar version mismatch where a different close symbol is scoped as array end, or malformed nesting such as '(text:1.2]' or '(text:1.2}'.
Common situations: Textmate grammar updates in the tokenizer whose scope names changed relative to what PromptSyntaxBuilder expects; prompts written with mismatched bracket types copied from other syntaxes.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Expected closing bracket.
- Unexpected end of input.
- Expected numeric weight value.
- Expected opening bracket.
- Expected network type.
AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12).
Data as JSON: /api/errors/dd508f63a710df35.
Report an issue: GitHub.
Appendix: source
Thrown at StabilityMatrix.Core/Models/PromptSyntax/PromptSyntaxBuilder.cs:218
if (weightToken is null || !weightToken.Scopes.Contains("constant.numeric"))
{
throw new InvalidOperationException("Expected numeric weight value.");
}
// Consume the weight token.
node.Weight = ParseNumber();
}
// We're supposed to check `punctuation.definition.array.end.prompt` here, textmate is not parsing it
// separately always with current tmLanguage grammar, so ALSO use `meta.structure.weight.prompt` for now
// We check this AFTER `punctuation.separator.weight.prompt` to avoid consuming the ':'
else if (
nextToken.Scopes.Contains("punctuation.definition.array.end.prompt")
|| nextToken.Scopes.Contains("meta.structure.weight.prompt")
)
{
// Verify contents
if (GetTextSubstring(nextToken) != ")")
throw new InvalidOperationException("Expected closing parenthesis.");
ConsumeToken(); // Consume the ')'
node.EndIndex = nextToken.EndIndex; // Set end index
break;
}
else
{
// It's part of the content.
node.Content.Add(ParseNode()); // Recursively parse nested nodes.
}
}
return node;
}
private NetworkNode ParseNetwork()
{
var beginNetworkToken = ConsumeToken();View on GitHub (pinned to af93d6ef57)