Skip to content

fix(build): tolerate unresolvable cargo metadata in filter discovery - #1024

Merged
leseb merged 1 commit into
praxis-proxy:mainfrom
Ladas:fix/build-script-metadata-fallback
Sep 10, 2026
Merged

fix(build): tolerate unresolvable cargo metadata in filter discovery#1024
leseb merged 1 commit into
praxis-proxy:mainfrom
Ladas:fix/build-script-metadata-fallback

Conversation

@Ladas

@Ladas Ladas commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Problem

server/build.rs panics when cargo metadata cannot resolve praxis-ai-proxy's
manifest on its own:

panicked at server/build.rs:50:
failed to run cargo metadata: ... failed to get `praxis-ai-apis` as a
dependency of package `praxis-ai-proxy v0.3.0 (/vendor/praxis-ai-proxy)`

This happens whenever the manifest is read away from its workspace. Two real cases:

  • cargo publish verification.
  • A vendored build: cargo vendor flattens the tree, so the manifest's
    path = "../apis" no longer points anywhere. This blocks hermetic container
    builds, where dependencies are prefetched and the build itself runs with no
    network.

Fix

Praxis core's equivalent script, crates/server/build.rs, already handles this:
load_metadata returns Option<Metadata> and main falls back to an empty
registration. Its doc comment names the same cause — "Returns None when metadata
resolution fails (e.g. during cargo publish verification where path dependencies
are not available)."

This restores that behaviour, which was lost when the discovery logic moved into
praxis-ai-build-support. One addition over core: the fallback emits a
cargo::warning, so a downstream crate that expected its filters to be discovered
can see why they were not.

Why this is safe

build_full_registry registers Praxis AI's own filters explicitly:

let mut registry = praxis_filter::FilterRegistry::with_builtins();
praxis_ai_filters::register_ai_filters(&mut registry, Some(subrequest_client));
register_llmd_ext_proc(&mut registry);
register_external_filters(&mut registry);   // generated by build.rs

The generated function only ever covers third-party crates carrying
[package.metadata.praxis-filters]. A server built in a vendored context keeps its
full built-in pipeline; only third-party discovery is skipped, and it now says so.

Verification

  • Vendored workspace built with --network none: before, aborted in this script;
    after, Finished release profile in 2m 10s and a working binary.
  • cargo +nightly fmt --check, cargo check -p praxis-ai-proxy (which runs the
    script), cargo clippy -p praxis-ai-proxy --all-targets -- -D warnings: clean.
  • cargo test -p praxis-ai-build-support: 10 passed. The fallback reuses
    generate_registration_code(&[]), already covered by
    generate_registration_code_emits_calls_and_empty_case_suppression.

No new tests: the change is in the build-script orchestrator, which by the file's own
note cannot carry unit tests; the logic it calls lives in build_support and is
unchanged.

Context

Found while making the experimental gateway image buildable by Konflux for an Open
Data Hub developer preview, where builds are hermetic. Opened as a draft for
maintainer review of the approach.

@Ladas
Ladas marked this pull request as ready for review September 9, 2026 10:33
@Ladas
Ladas requested review from a team and nerdalert September 9, 2026 10:33
@Ladas
Ladas force-pushed the fix/build-script-metadata-fallback branch 2 times, most recently from 4ca65d9 to 2dcbaca Compare September 9, 2026 12:14

@praxis-bot praxis-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

praxis-bot review: fix(build): tolerate unresolvable cargo metadata in filter discovery

Clean, well-motivated change that restores the graceful fallback Praxis core already has. The approach is correct: load_metadata and active_features return Option, main writes an empty registration on the fallback path, and emit_static_rerun_directives ensures Cargo will re-run discovery when the workspace is repaired. The added cargo::warning is a good improvement over core's silent .ok().

Findings

# Severity File Description
1 Medium server/build.rs Mixed Cargo directive syntax

Details below.

Comment thread server/build.rs
The build script panicked whenever `cargo metadata` could not resolve this
package's manifest in isolation. That happens whenever the manifest is read
away from its workspace: `cargo publish` verification, and vendored builds
such as a hermetic Konflux build, where `cargo vendor` flattens the tree so
the sibling `path` dependencies are no longer beside it.

Praxis core's equivalent build script already returns `Option` here and
degrades to an empty registration; this restores that behaviour, which was
lost when the discovery logic moved into praxis-ai-build-support.

Only discovery of external filter crates is affected. Praxis AI's own filters
are registered explicitly by `build_full_registry`, so a server built this way
still has its full built-in pipeline. Unlike core, the fallback also emits a
cargo warning, so a downstream crate that expected its filters to be
discovered can see why they were not.

Verified by vendoring the workspace and building it with the network
disabled: before, the build aborted in this script; after, it completes.

Signed-off-by: Ladislav Smola <lsmola@redhat.com>
@Ladas
Ladas force-pushed the fix/build-script-metadata-fallback branch from 2dcbaca to 50437c5 Compare September 10, 2026 08:49
@Ladas
Ladas requested a review from a team as a code owner September 10, 2026 08:49
@leseb
leseb added this pull request to the merge queue Sep 10, 2026
Merged via the queue into praxis-proxy:main with commit aae488c Sep 10, 2026
25 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.

3 participants