Troubleshooting¶
Errors print a red Pinfit error block with the offending file's path, often followed by a cyan hint
about the spec. Every spec is checked and every file rendered before the first write, so a failed
run changes no generated file. Two exceptions: an externalEnums: link that
@PinfitSwitch already wrote stays in its
.module.yaml, and a failing ss.cli run comes after the Pinfit-owned files of a
StateSmith machine were written.
Generation refuses to run¶
implements unknown interface '<name>'¶
The interface name is matched against the name: field of every .interface.yaml in the project,
not against a file name or a path. Check for a typo, and check the interface is inside this
project's tree — an interface in a nested project is invisible from
the outer one, and vice versa.
The same applies to references unknown ... from an observer's interface: or an adapter's
from: / to:.
maps unknown function '<name>'¶
An adapter mapping names a function that does not exist on the from or
to interface. Names are the YAML name: of the function, not the generated C identifier.
Refusing to overwrite non-Pinfit file <path>¶
Pinfit error
Refusing to overwrite non-Pinfit file D:\firmware\drivers\RA\ra_iic.c (use -f/--force to overwrite)
A file Pinfit was about to write already exists without its generated-file marker. This is the protection for a hand-written file that predates the spec.
Either point the spec at a different header: / source: name, or — once you are sure the file's
content is expendable and committed — pass --force.
<file> was edited outside its usercode regions since Pinfit last generated it¶
Someone changed the generated part of the file — by hand or with another tool. Regenerating would
overwrite that change, so Pinfit refuses. Move the change into a user region or into the YAML spec,
or pass --force to discard it. See
User regions.
found the old user-region marker syntax¶
The file still uses the /*@CGen(+name)*/ ... /*@CGen(-name)*/ regions of a very old version.
Change each region's two marker lines by hand to /*@Pinfit usercode+ name*/ and
/*@Pinfit usercode-*/, keeping the code between them. --force does not bypass this.
Multiple YAML specifications generate <file>¶
Two specs claim the same output path. Rename one, or move its YAML to another directory; generated files always land next to their spec.
Duplicate interface name / Multiple modules named '<name>'¶
Names are project-wide identifiers, so two specs cannot share one. This most often appears after
copy-pasting a spec file without changing name:.
Configuration errors¶
| Message | Fix |
|---|---|
format.indent must be between 2 and 8 |
Pick a value in that range. |
format.lineEnding must be lf or crlf |
Exactly those two spellings, lowercase. |
format.publicVariables must be extern or accessors |
Likewise. |
format.functionNaming must be snake_case or camelCase |
Note the mixed spelling: snake_case, camelCase. |
documentation.style must be doxygen, none, or custom |
Likewise. |
documentation.file is required when documentation.style is custom |
Add the path to your template YAML. |
Variable visibility errors¶
get/setunderextern— those two visibilities only exist underformat.publicVariables: accessors;externknows onlypublicandprivate. Switch the project setting, or usepublic.- An array marked
public,getorsetunderaccessors— C cannot return or take an array by value, soget_<name>/set_<name>cannot be generated. Keep array variablesprivate, or expose them aspublicunderextern.
@PinfitSwitch problems¶
It asks about the same enum every time¶
Confirmation is only remembered in an externalEnums: link on a .module.yaml. A @PinfitSwitch
inside a file owned by a state machine, observer, command table or adapter spec has nowhere to
record it. Declare the enum in a YAML enums: block instead.
Matched 'typedef enum' has no members¶
The fallback scan found the typedef but could not parse members out of it — usually a body built
from macros. Declare the enum in YAML enums:.
Cannot read linked enum file ... / Linked enum file ... no longer exists¶
An externalEnums: entry points at a file that has moved or been deleted. The file path is
relative to the YAML holding the entry. Fix the path, or delete the entry to be asked again.
Generation fails on a case label¶
A hand-written case in a tagged switch does not match any member of the enum. Pinfit fails rather
than silently dropping your code. Remove or correct that case, then generate again. See
@PinfitSwitch.
The same happens when you remove a member from the enum while its case region still holds code
(has code in the case for '<member>', which is no longer a member). Move or delete that code
first.
My code disappeared¶
It did not — Pinfit never deletes user region content. Check these in order:
- Was it inside a region? Only text between
usercode+andusercode-is preserved. Anything else in a generated file is rewritten every run. - Did the YAML item go away? A removed function or state leaves its region in the file as an orphan, no longer wrapped in anything. Search the file for the region name.
- Was the item renamed? That is a removal plus an addition: the old body is in the orphan region, and the new one is empty. Move the code across.
- Did you edit a marker line? The
usercode+line carries the name the next run matches on. If it was changed or deleted, the code is still in the file but no longer attached to anything — recover it from version control or by reading the file.
Run pinfit generate -v to see how many regions were carried over per file.
Nothing was generated¶
- Wrong directory.
generatescans from the directory you gave it, defaulting to the current one. The project root is found by walking up for apinfit.yaml, but the scan starts where you are. - The specs are in a nested project. A subdirectory with its own
pinfit.yamlis skipped entirely. Run Pinfit from inside it, or pass--also-nested. - File names. A spec has to be named
<name>.<kind>.yaml—door.state-machine.yaml, notdoor.statemachine.yamlordoor.yaml.
Use pinfit generate -v to print the project root and scope it actually used.
The generated code will not compile¶
- A changed signature. Editing
parametersorreturnrewrites the wrapper around your unchanged body. Fix the body. - Missing types. A type used in
context,variablesorparametersmust be reachable: add its header toincludes, or declare the type inenums/structs. - Missing
<stdbool.h>or<stdint.h>. Pinfit adds the standard headers its own generated code needs, but not the ones yourcontextandvariablestypes need — abool busyvariable needsincludes: [<stdbool.h>]in the spec. - Unprefixed standalone functions. A module's own
functions:are not module-prefixed, so two modules both declaringinitializecollide at link time. Keep those names unique yourself. pinfit_resultunused, or an earlyreturn. In a non-voidregion, assign topinfit_resultrather than returning. See MISRA.
Line endings churn in every diff¶
Set format.lineEnding explicitly and agree on one
value across the team; add a .gitattributes rule to match. Otherwise each person's generate
rewrites every file.
Still stuck¶
Run with -v for the project root, scope and per-file detail, and check the spec against the
YAML cheat sheet. If the behaviour still looks wrong, open an issue at
github.com/daoek/Pinfit/issues with the spec file and the
exact error text.