Skip to content

fix: remove content_category entrypoint heuristic that breaks re-deploys#4112

Merged
zackverham merged 1 commit into
mainfrom
fix/remove-content-category-entrypoint-heuristic-4110
May 1, 2026
Merged

fix: remove content_category entrypoint heuristic that breaks re-deploys#4112
zackverham merged 1 commit into
mainfrom
fix/remove-content-category-entrypoint-heuristic-4110

Conversation

@zackverham

@zackverham zackverham commented May 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #4110 — Re-deploying static HTML content fails with Connect error 110: "You cannot change the categorization of content once deployed."

Root cause

The contentCategoryField heuristic added in #4048 sets content_category: "site" in the deployment manifest whenever the entrypoint path starts with _site/ or _book/. This causes a regression for any content originally deployed without content_category (e.g., by an older Publisher version using the Go bundler, or by the TS bundler before #4048). Connect locks content_category after first deploy and rejects any change with error 110.

Investigation

We tested content_category: "site" against both standard Connect and Connect Cloud:

Standard Connect — deployed identical multi-page Quarto site bundles (including revealjs presentations) with and without content_category: "site":

  • Sub-page navigation: Works identically with and without content_category
  • Revealjs rendering: Works identically with and without content_category
  • Re-deploy with changed category: Reproduces error 110 as reported

Connect Cloud — deployed a multi-page Quarto site (including revealjs) without content_category: "site":

  • Sub-page navigation and revealjs rendering work correctly

content_category: "site" has no observable effect on content serving behavior for app_mode: "static" on either platform.

Fix

  • Removed the contentCategoryField entrypoint-path heuristic from manifestFromConfig.ts
  • The _site.yml / _bookdown.yml file detection in manifest.ts (carried over from the original Go implementation) is preserved — this only triggers when those config files are actually present in the bundle

Test plan

  • Unit tests updated in manifestFromConfig.test.ts — confirms content_category is not set from entrypoint path
  • Integration test updated in bundler.test.ts — confirms bundle for _site/ entrypoint does not include content_category
  • manifest.test.ts unchanged — _site.yml/_bookdown.yml detection still works
  • All 93 bundler tests pass
  • Lint passes
  • Manual testing: deployed multi-page Quarto sites (with revealjs) to Connect and Connect Cloud without content_category — all pages serve correctly

🤖 Generated with Claude Code

…oys (#4110)

The contentCategoryField heuristic (added in #4048) set content_category
to "site" in the manifest when the entrypoint path started with _site/
or _book/. This causes Connect error 110 on re-deploys of content that
was originally created without content_category, since Connect does not
allow changing categorization after first deploy.

Testing confirmed that content_category: "site" is not required for
Connect or Connect Cloud to correctly serve multi-page static HTML
sites, including revealjs presentations.

The _site.yml/_bookdown.yml detection in manifest.ts (carried over from
the original Go implementation) is preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zackverham zackverham changed the title fix: remove content_category entrypoint heuristic that breaks re-depl… fix: remove content_category entrypoint heuristic that breaks re-deploys May 1, 2026
@zackverham zackverham self-assigned this May 1, 2026
@zackverham zackverham marked this pull request as ready for review May 1, 2026 21:11
@zackverham zackverham requested a review from a team as a code owner May 1, 2026 21:11
@posit-connect-projects

posit-connect-projects Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished @zackverham's task in 1m 40s —— View job


Code Review Complete

  • Read changed files and understand the changes
  • Review code quality and correctness
  • Check test coverage
  • Provide review feedback

Review Summary

Verdict: Approve

This is a well-executed fix for a real regression. The PR correctly removes the problematic contentCategoryField heuristic while preserving the existing file-based detection mechanism.

What Changed

  1. manifestFromConfig.ts: Removed the contentCategoryField function and its invocation. This function set content_category: "site" based on entrypoint paths starting with _site/ or _book/ (-25 lines)

  2. manifestFromConfig.test.ts: Consolidated 6 test cases into 1 that verifies content_category is NOT set from entrypoint path (-49 lines)

  3. bundler.test.ts: Updated integration test to verify the bundle manifest doesn't include content_category from path detection (-26 lines)

Why This Fix Is Correct

The root cause analysis in the PR description is accurate:

  • Connect locks content_category after first deploy and rejects changes with error 110
  • The heuristic added in Fix Quarto website rendering and deployment for mixed-format projects #4048 could set content_category: "site" on re-deploys for content that was originally deployed without it
  • Testing confirmed content_category: "site" has no observable effect on app_mode: "static" content serving

Important Preservation

The PR correctly preserves the existing detection in manifest.ts:25-27:

if (KNOWN_SITE_CONFIG_FILES.includes(path.toLowerCase())) {
  manifest.metadata.content_category = "site";
}

This only triggers when _site.yml, _site.yaml, _bookdown.yml, or _bookdown.yaml config files are actually present in the bundle, which is the correct behavior.

Test Coverage

  • All 1637 unit tests pass (97 test files)
  • Test changes appropriately verify the new behavior (content_category NOT set from path)
  • The remaining test in manifest.test.ts continues to verify file-based detection works

Minor Observations

No issues found. The code removal is clean and focused. The test changes correctly flip from asserting toBe("site") to toBeUndefined().


@zackverham zackverham merged commit a56ee4d into main May 1, 2026
32 checks passed
@zackverham zackverham deleted the fix/remove-content-category-entrypoint-heuristic-4110 branch May 1, 2026 21:28
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.

Static HTML re-deploy fails with 403 error code 110 "cannot change categorization of content"

2 participants