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

  1. Use a matching ')' to close the parenthesized group
  2. Check the tokenizer/grammar (textmate) version matches what PromptSyntaxBuilder expects for scope names
  3. Verify the prompt has balanced, same-type brackets: '(a:1.1)' not '(a:1.1]'
  4. 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

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


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)