Skip to content

Bug: create_script validator false-positive — new Type(...) constructor calls misidentified as duplicate method declarations #1044

@TYQ12580

Description

@TYQ12580

Bug: create_script validator false-positive — new Type(...) constructor calls misidentified as duplicate method declarations

Summary

The regex-based "duplicate method signature" check in ManageScript.cs (around line 2742) incorrectly matches constructor invocations (new GameObject(...), new MaterialPropertyBlock(), etc.) as method declarations. When the same type is instantiated twice or more in a script, the validator rejects the file with:

ERROR: Duplicate method signature detected: 'GameObject' with 0 parameter(s). This may indicate a corrupted edit.

This is a false positive — the code is valid C# that compiles without issues in Unity.

Reproduction

Minimal failing case

using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        GameObject a = new GameObject("A");
        GameObject b = new GameObject("B");
    }
}

Result: create_script returns validation_failed with Duplicate method signature detected: 'GameObject' with 0 parameter(s).

More cases

Code pattern Result Expected
new GameObject("A") × 2 (same method) ❌ Rejected ✅ Should pass
new GameObject("A") in MethodA + new GameObject("B") in MethodB ❌ Rejected ✅ Should pass
new Vector3() × 2 ❌ Rejected ✅ Should pass
new MaterialPropertyBlock() × 2 ❌ Rejected ✅ Should pass
new GameObject("A") × 1 only ✅ Passes ✅ Correct
new GameObject("A") + new GameObject("B", typeof(SpriteRenderer)) (different param count) ✅ Passes ✅ Correct
new Vector3(1,0,0) × 2 (struct with args) ✅ Passes ✅ Correct

Root Cause

File: ManageScript.cs line ~2742
Regex:

var methodSigPattern = new Regex(
    @"(?:(?:public|private|protected|internal)\s+)?(?:(?:static|virtual|override|abstract|sealed|async|new)\s+)*\S+\s+(\w+)\s*\(([^)]*)\)\s*(?:where\s+\S+\s*:\s*\S+\s*)?(?:[{;]|=>)",
    RegexOptions.Multiline | RegexOptions.CultureInvariant, TimeSpan.FromSeconds(2));

The regex is designed to find method declarations like void DoSomething() {, but it also matches constructor calls like new GameObject("A"); because:

  1. new is consumed by the optional modifier group (?:static|virtual|...|new)
  2. The type name (e.g. GameObject) is consumed by \S+ (intended as "return type")
  3. The variable name or another token is captured by (\w+) as the "method name"
  4. The parenthesized arguments (...) match \(([^)]*)\)
  5. The trailing ; matches [{;]

The keyword filter at line ~2750 (IsCSharpKeyword) checks the captured method name, not the new keyword, so it doesn't help.

When the same constructor call appears twice, two identical "signatures" are recorded, triggering the duplicate check at line 2754-2756.

Suggested Fix

Add a negative lookbehind for new\s+ before the method name capture, or pre-filter matches where the \S+ token is preceded by =\s*new or (\s*new. For example:

// Option A: add negative lookbehind
@"(?<!new\s)(?:(?:public|private|protected|internal)\s+)?..."

// Option B: post-filter matches
if (Regex.IsMatch(codeOnly.Substring(Math.Max(0, sm.Index - 20), 20), @"=\s*new\s*$"))
    continue;

Impact

This bug blocks create_script for any non-trivial script that instantiates the same type more than once — which is extremely common in game development (spawning GameObjects, creating MaterialPropertyBlocks, etc.). Users must fall back to manual file creation outside MCP.

Environment

  • MCP for Unity version: 9.6.5 (commit 940831f)
  • Unity: 2022.3 LTS
  • Validation level: Basic

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions