Skip to content

NAME001: name-pattern

Name does not follow the configured naming convention

Code NAME001
Name name-pattern
Category Naming (NAME)
Default severity warning
Enabled by default no
Fix available sometimes
Fix safety safe or unsafe, depending on the finding (see below)
ign-lint equivalent NamePatternRule

Checks the names of components (meta.name), properties (custom properties, view parameters and the free-form keys inside them), message handlers (their messageType) and custom methods against a naming convention or a regular expression, with per-node-type settings. By default only component names are checked, against PascalCase, and root is skipped.

A failing name gets a suggestion in the configured convention. For components the suggestion is offered as a fix that renames the component and updates every reference to it in the view: property references in every binding and transform field Perspective parses as an expression ({../Label.props.text}, {/root/Panel/Label.custom.x}; the fields are measured in the Ignition image: expression bindings and structures, query parameters, tag paths and indirect references, polling rates, tag history date ranges and return sizes, HTTP URLs, bodies, header and authorization values, expression and map transforms), property binding paths, and literal getChild('...') / getSibling('...') calls in scripts whose receiver resolves (self, self.parent, self.view.rootContainer, earlier lookups). References are found by resolution, so a different component with the same name elsewhere in the view is left alone. The rename is unsafe when a script could find the component another way: it reads meta.name, or the component's name through the members measured to return it (self.name, c.getName(), also for a component reached through children, getChildren(), a loop or an index), looks children up with a computed name or a matching string, hands a component to code outside the view, reaches eval, locals() or a frame in any way (also under another name, __builtin__.eval), calls an unnamed value (factory()()), or calls a library name that is not a plain function, class or literal constant (it may be eval under another name; outside a project any such name counts).

The fix is offered only when every reference can be updated: a literal lookup on an unresolvable receiver naming the component, a suggestion that is taken by a sibling or that would itself break the convention, means no fix. It is safe when nothing could refer to the component in a way iglint cannot follow: no references at all, no script reads the component's name (meta.name, name, getName()), no script looks up children with computed names or has a string literal equal to the name, every script parses, no script hands a component to code outside the view (passing self, self.parent, event.source or another component to a library function, in a message payload, to getGlobals() or to any call iglint does not model): a library function that receives a component may call getChild('SaveButton') itself; no string of the view that iglint does not read as an expression or script holds a {...} reference (an action's settings, a field of an unknown binding type); no reference is written with whitespace inside its braces ({ ../Label.props.text }, which Perspective reads as a tag path); no string of the view holds the name, as a word, anywhere the fix does not update it; and the new name occurs nowhere in the view: not in any string of the view (a broken {../NewName.props.text} or binding path ../NewName.props.text would start to resolve) and not in any string literal of a script (self.getSibling('NewName'), which finds nothing now, would find the renamed component), in any spelling that differs only in case. Perspective compares names exactly, but case variants count too, to stay on the safe side. Fixed values of Perspective's schema are not searched for either name: a known component type (ia.input.button), a measured binding or transform type (query, expr-struct) and the keys leading to its parsed fields (struct), a known action type and scope, and the keys of meta other than name. It is unsafe otherwise, and names the place that keeps it from being safe. The safety net checks the result as well: a safe fix that changes what any reference of the view resolves to (see docs/internal/fix-safety.md, "Threat model") is reported as unsafe.

When a character of the name changes length under case mapping (the ligature fi upper-cases to FI, ß to SS), no suggestion and no fix are offered and the message says why. Like every fix, it is also 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").

Keys of props that the component's schema declares (text, style, pipes, ...) are Ignition's names, not yours, and are never checked; only free-form keys (for example the params passed to an embedded view) are. Style objects, position, private names (starting with _), Java dates and dataset internals are skipped.

Consistent names make views readable and make references such as {../SaveButton.props.enabled} predictable. Names with spaces or punctuation are easy to mistype in property paths and scripts.

With convention = "PascalCase":

{"meta": {"name": "save button"}, "type": "ia.input.button"}

Use instead:

{"meta": {"name": "SaveButton"}, "type": "ia.input.button"}
  • convention (unset by default): one of PascalCase, camelCase, snake_case, kebab-case, SCREAMING_SNAKE_CASE, Title Case, lower case. Unset means PascalCase without suggestions.
  • custom-pattern (unset by default): a regular expression (matched at the start of the name, like Python's re.match) that replaces the convention's pattern.
  • suggestion-convention (unset by default): the convention suggestions are written in, when it differs from convention (for example with a custom-pattern).
  • target-node-types (unset by default): node types to check: component, property, message_handler, custom_method. Defaults to the keys of per-type, or ["component"].
  • per-type (default {}): a table from node type to overrides of convention, pattern, pattern_description, suggestion_convention, min_length, max_length, forbidden_names, skip_names, severity and allow_numbers.
  • allow-numbers (default true): whether convention patterns accept digits.
  • min-length (default 1), max-length (unset by default): length limits (characters).
  • forbidden-names (default []): names that are always reported.
  • skip-names (default ["root"]): names never checked; giving a list replaces the default ["root"].
  • allowed-abbreviations (default []): extra abbreviations; an abbreviation written in capitals as a whole word is accepted where the convention writes words differently (read_API_data in snake_case, API Key in Title Case). In camelCase one of these is also accepted as the whole name or the first word (ID, IMLocation with ["ID", "IM"]); the built-in list of auto-detect-abbreviations is not, so HTTPServer is still reported.
  • auto-detect-abbreviations (default true): also use the built-in list (API, HTTP, ID, URL, ...).

Equivalent of NamePatternRule; every kwarg maps to the option of the same name (node_type_specific_rules is per-type) and iglint ign-lint prints the same messages. Intended differences (docs/compat/ign-lint-differences.md): abbreviations only ever widen what is accepted (ign-lint's substring replacement rejects idleTimer, restartButton or urlParams in camelCase and accepts any SCREAMING name containing an abbreviation); suggestions keep digits and split words consistently (badEmbeddedPotato_0 becomes BadEmbeddedPotato0, not Badembeddedpotato0); a component is never reported as colliding with its own name; schema-defined props keys and propConfig metadata are not properties; object-valued properties are checked too, not only leaves; renames update references by resolution and are unsafe when scripts could refer to the component dynamically.

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

Option Type Default Description
convention string none Naming convention of all node types.
custom-pattern string none Regular expression replacing the convention's pattern.
suggestion-convention string none Convention used for suggestions.
target-node-types array of strings none Node types to check.
per-type table {} Per node type overrides.
allow-numbers boolean true Whether convention patterns accept digits.
min-length integer 1 Minimum name length.
max-length integer none Maximum name length.
forbidden-names array of strings [] Names that are always reported.
skip-names array of strings ["root"] Names never checked.
allowed-abbreviations array of strings [] Extra abbreviations.
auto-detect-abbreviations boolean true Use the built-in abbreviation list.

ign-lint kwargs in a rule_config.json: convention -> convention, custom_pattern -> custom-pattern, suggestion_convention -> suggestion-convention, target_node_types -> target-node-types, node_type_specific_rules -> per-type, allow_numbers -> allow-numbers, min_length -> min-length, max_length -> max-length, forbidden_names -> forbidden-names, skip_names -> skip-names, allowed_abbreviations -> allowed-abbreviations, auto_detect_abbreviations -> auto-detect-abbreviations.


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