Problem
Views does the expensive work of initializing handlers at save time rather than at runtime, and bakes each display's max-age, cache contexts and cache tags into the view's own configuration. Whether an installing site gets that stored block or a fresh calculation depends on the core version: through 11.3 View::preSave() skips the calculation while syncing and for trusted data, which is how the config installer saves, so the exported block survives the install and is what the site runs on until somebody saves the view; from 11.4 the guard is only isSyncing(), so the block is recomputed on install and the file's value never applies.
What every version has in common is that the calculation is only worth what the handlers declare, and a field handler reaches a display's cacheability only by implementing CacheableDependencyInterface, which FieldPluginBase, unlike FilterPluginBase, does not. Seven columns resolve their value from something the view never queried and declare nothing at all: LinkedUserFieldBase behind the Assignee and Initiator columns, and WorkItemHolder, all three loading user entities; InstanceVariable, loading variable rows and date formats; NodeLabel, loading instances and workflows; WorkflowLabel, loading workflows; WorkItemOutcome, reading the node its token stands on; and the InstanceStatus field, reading the tenant's status terms. A column that declares nothing leaves a cached display saying what it said when it was rendered. No display carries a user list tag today, so renaming somebody would leave the old name on the page.
The exports are wrong on top of that. All seven shipped views export a max-age of zero and no cache tags at all, against a permanent max-age and between three and seven tags per display that the handlers compute, so the fifteen displays are uncached wherever the stored block still applies and the file misdescribes its own view everywhere else. Nothing notices: config schema types the block without knowing what belongs in it, and a handler tested through calculateCacheMetadata() answers for itself rather than for the file.
So the two halves are one issue, in this order. Regenerating the exports before fixing the handlers would turn fifteen uncached displays into fifteen displays that go stale.
Proposed resolution
Audit every views handler the project ships for what it reads beyond the row the view queried, and declare it. The per-viewer half of a decision never belongs there, because the view stores what it is given at save time; it travels on the render instead, as InstanceLinkFieldBase already does.
Then regenerate the cache_metadata block of all seven exported views, so a site installs the answer its own handlers give.
Two tests, because one alone proves little. One asserts per display that the file carries the block Views itself writes, which is what catches an export going stale again. The other names the columns and the tags each has to carry, because a comparison against a calculation holds just as well when the calculation is wrong.
This issue summary was drafted with the assistance of an AI agent (Claude). The analysis and the wording were reviewed by me before posting, and accountability for the content is mine.
Issue fork orchestra-3621245
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
mably commentedComment #4
mably commentedComment #6
mably commented