Skip to content

fix: pass Hub-hydrated harness-config path to harness.Resolve#450

Merged
ptone merged 2 commits into
GoogleCloudPlatform:mainfrom
ptone:scion/fix-harness-resolve-broker
Jun 19, 2026
Merged

fix: pass Hub-hydrated harness-config path to harness.Resolve#450
ptone merged 2 commits into
GoogleCloudPlatform:mainfrom
ptone:scion/fix-harness-resolve-broker

Conversation

@ptone

@ptone ptone commented Jun 19, 2026

Copy link
Copy Markdown
Member

Summary

  • In broker mode, harness.Resolve() used FindHarnessConfigDir which only searches local disk (template, project, global dirs). Hub-managed harness configs hydrated into temp directories were invisible to the resolver.
  • This caused Resolve to fall back to Generic{} with no command config, producing an empty shell command (sh -c "") — the agent exited immediately with code 0.
  • The bug affected all Hub-managed harness configs in broker mode, but was most visible with no-auth/drop-to-shell because the NoAuth config was also nil (preventing the drop-to-shell path from activating).
  • Fix: add ConfigDirPath to ResolveOptions so the broker can pass the Hub-hydrated path directly. run.go now passes opts.HarnessConfigPath through to the resolver.

Test plan

  • Start an agent with a Hub-managed harness config (e.g. antigravity) — verify the agent command runs (not empty)
  • Start an agent with no-auth selected on a harness config with no_auth.behavior: drop-to-shell — verify drop to bash shell with guidance message
  • Start an agent with a local (on-disk) harness config — verify no regression (ConfigDirPath is empty, falls through to FindHarnessConfigDir)
  • go test ./pkg/harness/... passes

In broker mode, harness.Resolve() used FindHarnessConfigDir which only
searches local disk. Hub-managed harness configs hydrated into temp
directories were invisible to the resolver, causing it to fall back to
a Generic{} harness with no command config. This produced an empty
shell command (sh -c "") and the agent exited immediately.

Add ConfigDirPath to ResolveOptions so the broker can pass the
Hub-hydrated path directly. This ensures the harness config (including
no_auth, command, provisioner) is loaded correctly in broker mode.
@google-cla

google-cla Bot commented Jun 19, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for an explicit harness configuration directory path (ConfigDirPath) in ResolveOptions, allowing the system to load the harness configuration directly from a specified path instead of relying solely on name-based lookups. The reviewer recommended that if an explicit ConfigDirPath is provided but fails to load, the error should be treated as a hard error and returned immediately rather than being silently ignored, to prevent unexpected behavior and ease debugging.

Comment thread pkg/harness/resolve.go
Comment on lines +71 to +77
var hcDir *config.HarnessConfigDir
var hcErr error
if opts.ConfigDirPath != "" {
hcDir, hcErr = config.LoadHarnessConfigDir(opts.ConfigDirPath)
} else {
hcDir, hcErr = config.FindHarnessConfigDir(opts.Name, opts.ProjectPath, opts.TemplatePaths...)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If an explicit ConfigDirPath is provided but fails to load (e.g., due to a missing or malformed config.yaml), silently ignoring the error and falling back to a generic or built-in harness can lead to unexpected behavior and make debugging difficult. Since the path is explicitly provided, any failure to load it should be treated as a hard error.

	var hcDir *config.HarnessConfigDir
	var hcErr error
	if opts.ConfigDirPath != "" {
		hcDir, hcErr = config.LoadHarnessConfigDir(opts.ConfigDirPath)
		if hcErr != nil {
			return nil, fmt.Errorf("failed to load explicit harness config directory %q: %w", opts.ConfigDirPath, hcErr)
		}
	} else {
		hcDir, hcErr = config.FindHarnessConfigDir(opts.Name, opts.ProjectPath, opts.TemplatePaths...)
	}

Same gap as run.go — provision.go:735 called harness.Resolve without
ConfigDirPath, so container-script harnesses were invisible in broker
mode during the provisioning step.
@ptone ptone merged commit 6d52d6a into GoogleCloudPlatform:main Jun 19, 2026
4 of 5 checks passed
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.

1 participant