Skip to content

fix(core): add LARKSUITE_CLI_FORCE_LOCAL escape hatch for inherited Agent env#1445

Open
nguyenngothuong wants to merge 1 commit into
larksuite:mainfrom
nguyenngothuong:fix/force-local-workspace-1405
Open

fix(core): add LARKSUITE_CLI_FORCE_LOCAL escape hatch for inherited Agent env#1445
nguyenngothuong wants to merge 1 commit into
larksuite:mainfrom
nguyenngothuong:fix/force-local-workspace-1405

Conversation

@nguyenngothuong

@nguyenngothuong nguyenngothuong commented Jun 13, 2026

Copy link
Copy Markdown

Summary

Fixes #1405.

Agent path variables such as HERMES_HOME / OPENCLAW_HOME are user-facing and get exported into shell profiles, so they are inherited by every child process — not just Agent subprocesses. Any unrelated automation that merely inherits HERMES_HOME is routed into the Hermes workspace and refuses to use its valid local lark-cli config, failing with:

{ "ok": false, "error": { "type": "config", "subtype": "not_configured",
  "message": "hermes context detected but lark-cli is not bound to it" } }

This implements option 3 from the issue: a documented way to force normal local config mode without unsetting the inherited variable.

Change

DetectWorkspaceFromEnv now honors LARKSUITE_CLI_FORCE_LOCAL == "1" as a priority-0 escape hatch that returns WorkspaceLocal, overriding every Agent signal. The check uses the same strict == "1" convention as OPENCLAW_CLI / HERMES_QUIET / LARK_CHANNEL, and the env-var naming matches the existing LARKSUITE_CLI_CONFIG_DIR.

The agent "not bound" hint now mentions the escape hatch so operators who hit the wall can discover it.

# inherited HERMES_HOME → hijacked into hermes context (the bug)
HERMES_HOME=/some/path lark-cli config show
#   → "hermes context detected but lark-cli is not bound to it"

# escape hatch → back to the normal local config
HERMES_HOME=/some/path LARKSUITE_CLI_FORCE_LOCAL=1 lark-cli config show
#   → uses local ~/.lark-cli config as before

Notes

  • The "bind ignores HERMES_HOME" part of the issue appears already addressed on main: resolveHermesEnvPath() (cmd/config/binder.go) already respects HERMES_HOME. This PR targets the remaining root cause — false-positive workspace detection.
  • Scope is intentionally minimal (the escape hatch). Happy to follow up on a narrower detection model for Hermes (e.g. a subprocess marker like OpenClaw's OPENCLAW_CLI, downgrading HERMES_HOME to a secondary signal) if maintainers prefer that direction.

Tests

  • New table cases in workspace_test.go covering override-of-HERMES_HOME, override-of-all-signals, strict == "1" parsing (true/0 ignored), and the no-op case.
  • Updated the e2e unbound-workspace hint assertion.
  • go build ./..., gofmt, go vet, and go test ./internal/core/... + the e2e config suite pass locally.

Summary by CodeRabbit

  • New Features

    • Added an escape hatch mechanism to force use of local configuration, allowing users to bypass inherited workspace detection settings when needed.
  • Documentation

    • Enhanced configuration binding guidance with additional instructions for cases where inherited context is triggered and users prefer local configuration.
  • Tests

    • Added comprehensive test cases validating the override mechanism behavior across multiple configuration scenarios.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 93c456fe-f519-42fe-9fe4-94aceb5a7b1c

📥 Commits

Reviewing files that changed from the base of the PR and between e1af7e3 and 17a2dc2.

📒 Files selected for processing (4)
  • internal/core/notconfigured.go
  • internal/core/workspace.go
  • internal/core/workspace_test.go
  • tests/cli_e2e/config/bind_test.go

📝 Walkthrough

Walkthrough

This PR implements a workspace detection escape hatch by introducing the LARKSUITE_CLI_FORCE_LOCAL=1 environment variable override. When set to exactly "1", it forces local configuration mode and bypasses all inherited Agent context signals, resolving the issue where unrelated automation processes inheriting HERMES_HOME unexpectedly enter Agent context.

Changes

Agent/Hermes Context Escape Hatch

Layer / File(s) Summary
Workspace detection escape hatch implementation and test coverage
internal/core/workspace.go, internal/core/workspace_test.go, internal/core/notconfigured.go, tests/cli_e2e/config/bind_test.go
DetectWorkspaceFromEnv now checks LARKSUITE_CLI_FORCE_LOCAL as the highest-priority detection rule: when set to exactly "1", it immediately returns WorkspaceLocal regardless of inherited HERMES_HOME, OPENCLAW_CLI, or other Agent signals. Documentation is expanded to explain this priority. Test coverage validates strict "1" matching (ignoring "true" and "0"), override behavior against multiple Agent signals, and interaction with HERMES_HOME. User-facing hint text in the bind workflow is updated to instruct users on setting this override when Agent context was inherited unintentionally.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • larksuite/cli#786: Both PRs modify environment-driven workspace routing in internal/core/workspace.go—the retrieved PR adds LARK_CHANNEL/WorkspaceLarkChannel detection while this PR changes DetectWorkspaceFromEnv to override that detection when LARKSUITE_CLI_FORCE_LOCAL=1.

Suggested labels

size/L

Suggested reviewers

  • liangshuo-1

Poem

🐰 A rabbit hops through inherited vines,
But finds a magic spell—FORCE_LOCAL=1
No more Agent chains when contexts combine,
Just local configs, shining in the sun. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.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 clearly summarizes the main change: adding a LARKSUITE_CLI_FORCE_LOCAL escape hatch for inherited Agent environment variables.
Description check ✅ Passed The description fully covers the template sections: Summary explains the issue and references #1405, Changes details the implementation, Tests describes verification steps and results.
Linked Issues check ✅ Passed The PR implements option 3 from #1405: providing a documented escape hatch (LARKSUITE_CLI_FORCE_LOCAL=1) to force normal local config mode, which was the primary goal of the linked issue.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the escape hatch and updating related guidance. No unrelated modifications were introduced.

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

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

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

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

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jun 13, 2026
…gent env

Agent path variables such as HERMES_HOME / OPENCLAW_HOME are user-facing and
get exported into shell profiles, so they are inherited by every child
process. Unrelated automation that merely inherits HERMES_HOME was routed into
the Hermes workspace and refused to use its valid local lark-cli config,
failing with "hermes context detected but lark-cli is not bound to it"
(issue larksuite#1405).

DetectWorkspaceFromEnv now honors LARKSUITE_CLI_FORCE_LOCAL == "1" as a
priority-0 escape hatch that forces WorkspaceLocal, overriding every Agent
signal without requiring the inherited variable to be unset. The agent "not
bound" hint now mentions this escape hatch so operators hitting the wall can
discover it.
@nguyenngothuong
nguyenngothuong force-pushed the fix/force-local-workspace-1405 branch from 95bf478 to 17a2dc2 Compare June 13, 2026 02:53
@github-actions github-actions Bot added size/M Single-domain feat or fix with limited business impact and removed size/L Large or sensitive change across domains or core paths labels Jun 13, 2026
@evandance

Copy link
Copy Markdown
Collaborator

Thanks for the PR and the clear root-cause notes — the analysis of where the signal comes from is genuinely helpful.

The bind-path part needs no change. On main (and already in 1.0.51) config bind resolves the path from HERMES_HOME and only falls back to the default when it's unset. Within a single run, detection and path resolution read the same HERMES_HOME, so they can't point at different locations — the default-path output only appears when HERMES_HOME is empty. So there's nothing to fix on that half.

For the escape hatch, I don't think we should merge it. Here's the reasoning.

"Context detected but not bound" is not a bug — it's how the isolation is meant to work. config bind keeps each Agent's credentials separate so that an Agent context never quietly reuses the developer's personal local config.

The real question is why HERMES_HOME is visible to a job that isn't a Hermes job. Hermes sets that variable per-process for the processes it launches; a normal install does not put it in a global shell profile or system environment. (The Docker image sets it container-wide, but that container is a Hermes context.) So a global HERMES_HOME that unrelated jobs inherit is an environment problem, and it should be fixed where the variable is set — not worked around in the CLI.

A permanent LARKSUITE_CLI_FORCE_LOCAL flag also opens a hole in that isolation. It uses the same channel that caused the problem — environment variables — to switch the CLI back to the developer's identity inside an Agent context. Anything that can set an env var could flip it. We'd rather not trade that safety property for a workaround to a misconfigured environment.

Two smaller points:

  • The code comment says the agents export HERMES_HOME / OPENCLAW_HOME into shell profiles. They don't, so that shouldn't be the stated reason.
  • I'd also hold off on demoting HERMES_HOME to a secondary signal. Some Hermes processes set only HERMES_HOME, so demoting it would break detection for real Hermes subprocesses, and the CLI can't rely on a marker Hermes doesn't send.

I've left guidance on the issue for the reporter on how to scope the variable. Thanks again for the careful work.

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

Labels

size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lark-cli enters Hermes context when HERMES_HOME is inherited, then bind ignores HERMES_HOME path

2 participants