Skip to content

VIEW013: property-persistence

Bound custom property persistence differs from the project convention

Code VIEW013
Name property-persistence
Category View structure (VIEW)
Default severity warning
Enabled by default no
Fix available sometimes
Fix safety safe or unsafe, depending on the finding (see below)
ign-lint equivalent PropertyPersistenceRule

Checks persistent on the propConfig entries of bound custom properties (custom.* entries with a binding, view level and components) against expected-persistent. A missing persistent means persistent. Nothing is checked until expected-persistent is set.

  • expected-persistent = false: reports bound properties that are persistent. The Designer then writes every binding result into view.json, which bloats the file and produces noisy diffs.
  • expected-persistent = true: reports bound properties that are not persistent, and persistent ones without a stored default value.

A bound, persistent property stores the Designer's last binding result in the resource. Query results and tag values end up in version control and change on every save.

With expected-persistent = false:

{"custom": {"rows": [1, 2, 3]},
"propConfig": {"custom.rows": {"binding": {"type": "query", "config": {"queryPath": "Rows"}}}}}

Use instead:

{"custom": {},
"propConfig": {"custom.rows": {"binding": {"type": "query", "config": {"queryPath": "Rows"}}, "persistent": false}}}
  • expected-persistent (unset by default): true or false; unset disables the rule.
  • exempt-binding-types (default ["tag"]): binding types that are not checked: expr, expr-struct, property, query, tag (every tag mode), tag.direct, tag.indirect, tag.expression, and the other registered types (tag-history, http). Default ["tag"]; [] checks everything.

For expected-persistent = false: sets persistent: false and removes the stored value (when its path has no array index). Safe when there is no stored value (the property starts out absent either way). Unsafe when there is one: until the binding delivers its first value (query bindings are asynchronous), startup scripts, change scripts and expressions see the stored value before the fix and no value after it.

Like every fix, it is unsafe while code in the workspace may read the files a fix edits (any file access, read, write, rename or delete, whose path is not a literal outside the workspace, or code that is not vetted); the project setting [fix] assume-scripts-do-not-read-workspace-files = true declares that no script does (see docs/internal/fix-safety.md, "File reads").

Equivalent of PropertyPersistenceRule (expected_persistent, exempt_binding_types), with the same messages in iglint ign-lint.

Set in [rules.VIEW013] of iglint.toml (or [tool.iglint.rules.VIEW013] in pyproject.toml).

Option Type Default Description
expected-persistent boolean none Whether bound custom properties must be persistent.
exempt-binding-types array of strings ["tag"] Binding types that are not checked.

ign-lint kwargs in a rule_config.json: expected_persistent -> expected-persistent, exempt_binding_types -> exempt-binding-types.


Generated from the rule metadata by iglint generate-docs; iglint rule VIEW013 prints the same page in the terminal. Source: docs/rules/VIEW013.md.