Avertissements
Une recette malformée ou incomplète finit quand même de compiler : le compilateur et l’Analyseur collectent des objets Warning structurés au lieu de lever des exceptions. Cela permet d’afficher la recette tout en signalant visuellement les avertissements. L’énumération WarningCode et ses utilitaires sont exportés par @gram-lang/kitchen.
L’interface Warning
Section intitulée « L’interface Warning »compile() les retourne dans le tableau CompilationResult.warnings. De son côté, analyze() les propage (et en ajoute potentiellement de nouveaux) dans AnalyzedCompilationResult.warnings. Ce ne sont jamais de simples chaînes de caractères : le champ .message est toujours garanti.
Sévérité & --strict
Section intitulée « Sévérité & --strict »Les problèmes d’intégrité structurelle (une référence vers un élément fantôme, une collision de noms, un module introuvable, etc.) sont de sévérité error. Les lacunes récupérables (estimations, annotations incomplètes) sont catégorisées en warning, et les simples notifications contextuelles (surplus, calcul par fournées, contention de ressources) sont en info. Ainsi, une unité de minuteur manquante ne fera pas crasher un build au même titre qu’une référence indéfinie. C’est exactement sur cette distinction que repose l’option --strict de la commande CLI gram check : sans --strict, seuls les codes de sévérité error font échouer la commande ; avec, chaque warning et info est promu en error. Vous pouvez facilement coder votre propre logique de mode strict en vous appuyant sur le dictionnaire warningSeverity[code].
| Code | Sévérité | Modèle de message |
|---|---|---|
VARIABLE_NOT_FOUND | warning | Cannot resolve relative quantity: target intermediate '&{targetName}' is not defined. |
RELATIVE_QUANTITY_UNRESOLVED | warning | Cannot resolve relative quantity: target ingredient '@{targetName}' was not found in the current section. |
RELATIVE_QUANTITY_UNKNOWN_MASS | warning | Cannot compute relative quantity for '{item}': mass of target '{targetName}' is unknown. |
CIRCULAR_REFERENCE | error | Circular reference detected: '{name}' depends on itself. |
UNDEFINED_REFERENCE | error | Undefined reference '{prefix}{name}' — no prior step or section produces this item. |
MISSING_UNIT | warning | {type} requires an explicit unit (e.g. min, s, °C). |
INVALID_UNIT | warning | Invalid unit "{value}" for {type}. |
SCOPE_CONFLICT | error | Intermediate variable '&{varName}' is redefined; variable names must be unique across the recipe. |
MISSING_INGREDIENT | warning | Ingredient "{id}" not found in database — nutritional metrics and density conversions unavailable. |
MISSING_MACROS | info | Ingredient "{id}" has no macronutrient data in database — nutritional totals are partial. |
UNKNOWN_MASS | info | Cannot calculate mass for "{id}" — omitted from nutritional totals. |
INVALID_MODIFIER_COMBINATION | warning | Incompatible modifiers on "{item}": {combination}. |
COMPOSITE_PARENT_CONFLICT | error | Composite child "{childName}" was already linked to parent "{previousParent}" — using it with a different parent "{newParent}" here means both will share the same database entry, which is very likely wrong. |
INVALID_BAKERS_REFERENCE | warning | '{item}' cannot be used as the Baker's percentage reference (*). |
NO_BAKERS_REFERENCE | warning | Baker's percentages (%) are used but no base flour (*) was designated. |
TIME_PARADOX | warning | Timeline conflict: {cause} is pulled earlier than recipe start to satisfy {conflict}. |
TRACK_CONTENTION | info | Resource contention on track '{trackName}': delayed by {delay} min for '{item}'. |
MODULE_NOT_FOUND | error | Module "{specifier}" could not be found or resolved. |
MODULE_PARSE_ERROR | error | Syntax error in imported module "{specifier}": {parseMessage} |
MODULE_CYCLE | error | Circular module import detected: {chain}. |
MODULE_DEPTH_EXCEEDED | error | Import depth limit exceeded ({depth}) while importing "{specifier}". |
MODULE_EXPORT_NOT_FOUND | error | Module "{specifier}" does not export '&{exported}' — it exists in the module but isn't re-exported. Add '-> &{exported}' to the section that produces it. |
UNUSED_IMPORT | warning | Unused import '&{local}' from "{specifier}". |
UNRESOLVED_MODULE_YIELD | error | Cannot compute yield for '&{binding}' from "{specifier}": missing physical mass data for one or more ingredients. |
ESTIMATED_MODULE_YIELD | warning | Yield of '&{binding}' from "{specifier}" is estimated using standard ingredient densities or unit weights. Scale factor is approximate. |
MODULE_UNIT_MISMATCH | error | Unit mismatch for '&{binding}' from "{specifier}": requested in '{requestedUnit}' but yields in '{yieldUnit}' without a conversion density. |
MODULE_BATCH_INTERPRETATION | info | '&{binding}' from "{specifier}" requested without unit — scaled as {batches} batch(es) of the module. |
IMPORTED_BAKERS_REFERENCE_DROPPED | info | Baker's percentage base (*) from "{specifier}" is scoped to its own module and was not imported. |
DENSITY_OVERRIDE_SHADOWED | info | Density for "{ingredient}" in host recipe ({hostValue}) overrides module "{specifier}" ({moduleValue}). |
MODULE_SURPLUS | info | Scaling "{specifier}" for '&{binding}' yields a surplus: {surplus}. |
MODULE_SPECIFIER_INVALID | error | Invalid module path "{specifier}": {reason} |
MODULE_SCHEME_UNSUPPORTED | error | Unsupported URL scheme in module specifier: "{specifier}". |
STOCKED_RETRO_PLANNING_IGNORED | warning | Stocked module "{specifier}" has a retro-planning offset "~{...}", which is ignored because stocked items require no prep time. |
RETRO_PLANNING_OVERRIDE_SHADOWED | info | Host retro-planning offset on "@use {specifier}" overrides the module's internal offset. |
MODULE_BINDING_SHADOWS_INGREDIENT | warning | Imported binding '&{binding}' from "{specifier}" shares name with a database ingredient. |
STOCKED_DESTRUCTURED_NUTRITION_BLENDED | info | Stocked module "{specifier}" uses destructured imports — nutrition profile is averaged across the entire module. |
VARIABLE_NOT_FOUND
Section intitulée « VARIABLE_NOT_FOUND »Une quantité relative référence une variable intermédiaire (50% of &nom) qui n’a été déclarée nulle part dans la recette comme sortie intermédiaire (>> nom). Correction : déclarez la variable avant de la référencer, ou corrigez la faute de frappe.
RELATIVE_QUANTITY_UNRESOLVED
Section intitulée « RELATIVE_QUANTITY_UNRESOLVED »Une quantité relative cible un ingrédient (50% of @nom) qui n’est pas apparu plus tôt dans la même section. Attention, contrairement aux variables, les cibles relatives aux ingrédients sont scopées par section. Correction : déplacez l’ingrédient cible plus haut dans la même section, ou passez par une variable intermédiaire (&nom) si la portée doit être globale.
RELATIVE_QUANTITY_UNKNOWN_MASS
Section intitulée « RELATIVE_QUANTITY_UNKNOWN_MASS »Émis pendant l’analyse : la cible d’une quantité relative a bien été trouvée, mais sa propre masse est incalculable (unité/densité introuvable). Le pourcentage ne peut donc pas s’appliquer. Correction : attribuez à l’ingrédient cible une unité standardisable, ou renseignez sa densité / son unit_weight dans la base de données.
CIRCULAR_REFERENCE
Section intitulée « CIRCULAR_REFERENCE »La quantité relative d’un ingrédient se cible elle-même (@farine{50% of @farine}). Correction : supprimez l’auto-référence (une quantité relative doit pointer vers un ingrédient ou une variable différente).
UNDEFINED_REFERENCE
Section intitulée « UNDEFINED_REFERENCE »Une référence pure (&nom) ou un ingrédient référençable (@&nom) pointe vers un élément qui n’a jamais été enregistré en amont de la recette. Correction : introduisez l’ingrédient (sans &) avant de le référencer, ou corrigez la faute de frappe.
MISSING_UNIT
Section intitulée « MISSING_UNIT »Un Timer (minuteur) ou une Temperature a été écrit sans unité explicite (ex. ~{10} au lieu de ~{10 min}). Correction : ajoutez l’unité manquante.
INVALID_UNIT
Section intitulée « INVALID_UNIT »Soit un Timer a reçu une quantité non numérique (du texte), soit une Temperature a reçu une unité autre que Celsius ou Fahrenheit. Correction : utilisez une valeur numérique couplée à une unité temporelle reconnue pour les minuteurs, et limitez-vous à °C ou °F pour les températures.
SCOPE_CONFLICT
Section intitulée « SCOPE_CONFLICT »Deux sections déclarent un même nom de variable (>> nom). Les noms de variables doivent être uniques à l’échelle de toute la recette, pas juste de la section. Correction : renommez l’une des deux variables.
MISSING_INGREDIENT
Section intitulée « MISSING_INGREDIENT »Lors de l’estimation nutritionnelle, un ingrédient (dont on connaît la masse) n’a trouvé aucune correspondance (par ID ou alias) dans la base de données. Correction : ajoutez l’ingrédient ou son alias dans votre base.
MISSING_MACROS
Section intitulée « MISSING_MACROS »L’ingrédient a bien été trouvé en base, mais ne possède aucun bloc nutrition. Correction : documentez le bloc nutrition dans l’entrée YAML correspondante.
UNKNOWN_MASS
Section intitulée « UNKNOWN_MASS »L’Analyseur n’a pu résoudre aucune masse pour cet ingrédient (unité inexploitable, aucune densité/unit_weight), il est donc exclu des totaux nutritionnels. Correction : comme pour RELATIVE_QUANTITY_UNKNOWN_MASS, fournissez une unité standardisable ou des données physiques en base.
INVALID_MODIFIER_COMBINATION
Section intitulée « INVALID_MODIFIER_COMBINATION »Modificateurs en conflit ou dupliqués sur un même ingrédient/matériel. Par exemple : optional (?) couplé à important (*), ou hidden (-) avec referenceable (&). La collision exacte est détaillée dans le .message. Correction : retirez le modificateur incriminé.
INVALID_BAKERS_REFERENCE
Section intitulée « INVALID_BAKERS_REFERENCE »L’ingrédient marqué comme ancre du % boulanger (via le modificateur * ou l’option bakersReference) possède lui-même une masse dérivée (quantité relative par rapport à un autre ingrédient). Il ne peut donc pas servir de base à 100 % (dépendance circulaire). Correction : choisissez un ingrédient doté d’une quantité absolue pour servir de point de référence.
NO_BAKERS_REFERENCE
Section intitulée « NO_BAKERS_REFERENCE »Le mode Baker’s Math a été explicitement requis (via enableBakersMath avec un modificateur * nu, ou via un identifiant bakersReference), mais aucun ingrédient correspondant n’a été trouvé. Correction : ajoutez le modificateur * sur un ingrédient, ou corrigez l’ID passé à bakersReference.
COMPOSITE_PARENT_CONFLICT
Section intitulée « COMPOSITE_PARENT_CONFLICT »Un nom court d’ingrédient composite (ex : @jus) est extrait de deux parents différents dans la même recette (ex : <@citron dans une étape et <@orange dans une autre). Correction : utilisez le nom complet de l’enfant (ex : @jus de citron et @jus d'orange) pour éviter les collisions d’identité dans la base de données.
MODULE_NOT_FOUND
Section intitulée « MODULE_NOT_FOUND »Un module importé via une directive @use n’a pas pu être résolu ou trouvé sur le système de fichiers. Correction : vérifiez le chemin du fichier, l’extension (.gram) ou les alias configurés dans config.yaml.