Skip to content

Fix internal prefix exposed in redeclared worker symbol diagnostic#44583

Open
notdulain wants to merge 1 commit intoballerina-platform:masterfrom
notdulain:master
Open

Fix internal prefix exposed in redeclared worker symbol diagnostic#44583
notdulain wants to merge 1 commit intoballerina-platform:masterfrom
notdulain:master

Conversation

@notdulain
Copy link
Copy Markdown

@notdulain notdulain commented May 3, 2026

Purpose

Fixes #44468

When a named worker is declared inside a fork block, the compiler internally stores it as a lambda variable with a 0 prefix (e.g. 0worker1) to avoid name collisions in the
surrounding scope. If the same worker name is declared twice within the same fork, SymbolResolver.checkForUniqueSymbol detects the collision and reports a REDECLARED_SYMBOL
diagnostic using the internal symbol name, leaking the implementation detail to the user:

error: redeclared symbol '0worker1'

The user-facing diagnostic should reference the source name they actually wrote (worker1), not the internal lambda variable name.

Reproducer

public function main() {
    fork {
        worker worker1 {
        }                                                                                                                                                                            
        worker worker1 {
        }                                                                                                                                                                            
    }                                                                                                                                                                              
}

Approach

In SymbolResolver.checkForUniqueSymbol, before constructing the REDECLARED_SYMBOL (and UNSUPPORTED_REMOTE_METHOD_NAME_IN_SCOPE) diagnostic, strip the WORKER_LAMBDA_VAR_PREFIX ("0")
from the symbol name when it is present. This keeps the internal naming scheme intact for symbol resolution while ensuring the user-facing message shows the original source name:

error: redeclared symbol 'worker1'

The change is local to the diagnostic construction path and does not affect symbol lookup, scoping, or codegen.

Samples

N/A — diagnostic message fix.

Remarks

None

Check List

  • Read the Contributing Guide
  • Updated Change Log
  • Checked Tooling Support (#)
  • Added necessary tests
    • Unit Tests
    • Spec Conformance Tests
    • Integration Tests
    • Ballerina By Example Tests
  • Increased Test Coverage
  • Added necessary documentation
    • API documentation
    • Module documentation in Module.md files
    • Ballerina By Examples

Summary

This pull request improves the clarity of compiler diagnostic messages for duplicate worker declarations in fork blocks. When multiple workers with the same name are declared within a fork, the compiler internally uses a lambda-variable prefix for tracking purposes. Previously, this implementation detail would leak into error messages, showing users internal names like "0worker1" instead of the source names they wrote.

Changes

Compiler Logic (SymbolResolver.java)

  • Enhanced symbol validation to normalize internal names when constructing diagnostic messages
  • When a redeclared symbol's name contains the lambda-variable prefix, the prefix is stripped before generating the error message
  • This ensures users receive clear, readable error messages showing the original symbol names they wrote
  • The underlying symbol lookup and scoping logic remains unchanged

Test Coverage

  • Added a new test method to validate the behavior with duplicate worker declarations in fork blocks
  • Added a negative test case file containing a fork with two workers declared using the same identifier
  • Tests verify that compilation fails with the expected redeclaration error and that the error message displays the correct symbol name

Impact

Users will now receive clearer diagnostic messages for duplicate worker declarations, with error messages referencing the actual symbol names from their source code rather than internal compiler representations.

…nostic

When a named worker is declared inside a fork block, the compiler
internally stores it as a lambda variable with a '0' prefix (e.g.
'0worker1') to avoid name collisions in the surrounding scope.

If the same worker name is declared twice within the same fork block,
SymbolResolver.checkForUniqueSymbol detects the collision and reports
a REDECLARED_SYMBOL diagnostic using the internal symbol name, which
exposes the implementation detail to the user as:
  "redeclared symbol '0worker1'"

Strip the WORKER_LAMBDA_VAR_PREFIX from the name before building the
diagnostic so the message shows the source name the user actually wrote:
  "redeclared symbol 'worker1'"

Adds a regression test covering duplicate worker declarations in a fork.

Fixes: ballerina-platform#44468
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 981df9f4-3c73-4f06-9d37-ce6b0b63b586

📥 Commits

Reviewing files that changed from the base of the PR and between f59068a and d1e93b5.

📒 Files selected for processing (3)
  • compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolResolver.java
  • tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/BasicForkNegativeTest.java
  • tests/jballerina-unit-test/src/test/resources/test-src/workers/fork_duplicate_worker_negative.bal

📝 Walkthrough

Walkthrough

A bug fix for duplicate worker name diagnostics: SymbolResolver now strips the worker lambda variable prefix when validating redeclared symbols, ensuring diagnostic messages display clean symbol names. A test case and corresponding test resource verify the fix.

Changes

Worker Duplicate Diagnostic Normalization

Layer / File(s) Summary
Core Logic
compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolResolver.java
Added import of WORKER_LAMBDA_VAR_PREFIX and modified checkForUniqueSymbol() to strip this prefix from redeclared symbol names before diagnostic processing, preventing internal prefixes from appearing in user-facing error messages.
Test Fixture
tests/jballerina-unit-test/src/test/resources/test-src/workers/fork_duplicate_worker_negative.bal
New negative test scenario with a fork containing two workers named worker1, demonstrating the duplicate worker case.
Test Validation
tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/BasicForkNegativeTest.java
Added testDuplicateWorkerInFork() method that compiles the test fixture and validates the redeclared symbol error appears with the clean symbol name at the expected location.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A rabbit hops through symbols deep,
Where worker names no longer creep
With cryptic prefixes in sight—
Now "worker1" shines clear and bright! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing the exposure of an internal prefix in worker symbol redeclaration diagnostics.
Description check ✅ Passed The description covers the purpose, approach, and samples sections, explaining the issue and solution clearly. Some optional items in the checklist are unchecked but not required.
Linked Issues check ✅ Passed The PR successfully addresses issue #44468 by stripping the WORKER_LAMBDA_VAR_PREFIX from symbol names in diagnostic messages, ensuring user-facing errors show original source names.
Out of Scope Changes check ✅ Passed All changes are scoped to the issue: modifying SymbolResolver diagnostic construction and adding corresponding unit tests for duplicate worker validation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@notdulain
Copy link
Copy Markdown
Author

CI Failures — Both Unrelated to This PR

This PR only touches SymbolResolver.java, BasicForkNegativeTest.java, and the associated .bal test file. Neither CI failure is caused by these changes.


🐧 Ubuntu — Pre-existing master breakage (Stdlib Level failures)

All stdlib level failures (levels 1, 7, 8, 10) trace to a single root cause: module-ballerina-observe fails to compile against master:

.../observe/nativeimpl/GetTagValue.java:32: error: cannot find symbol
  symbol:   method getCustomTag(String)
  location: class ObserveUtils

ObserveUtils.getCustomTag(String) was introduced in 2201.13.x-private-releases (commit cbfda310351) but has never been ported to master. The observe stdlib already calls it, so the build breaks. The cascade of No such file or directory errors in downstream levels is a knock-on effect of the failed observe build.

This will affect every PR targeting master until one of the following is resolved upstream:

  • getCustomTag is backported to master's ObserveUtils, or
  • The observe stdlib is rolled back to not call it.

🪟 Windows — Flaky shell integration test

io.ballerina.shell.cli.test.integration.BasicsEvaluatorTest
  > testEvaluateBasicsFunctions FAILED
    java.io.IOError: java.io.IOException: Pipe broken
      at org.jline.keymap.BindingReader.readCharacter(...)

This is a known JLine REPL terminal pipe-broken flake on Windows, completely unrelated to the symbol resolver changes in this PR. Re-running the job should clear it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Irrelevent diagnostic shown for workers with same identifier

2 participants