File-New-Project/EarTrumpet · error · NotImplementedException

Missing resource: {res}

Error message

Missing resource: {res}

What it means

TextViewModel wraps an IPartWithText and exposes PromptText (always) and EmptyText (from ToString when the part's Text is blank). ResolveResource builds "{_part.GetType().Name}_{suffix}", so the CONCRETE runtime type behind the IPartWithText interface must supply "{ConcreteType}_PromptText" and "{ConcreteType}_EmptyText" resx strings. Missing either throws NotImplementedException.

Source

Thrown at EarTrumpet/Addons/EarTrumpet.Actions/ViewModel/TextViewModel.cs:45

        public override string ToString()
        {
            if (string.IsNullOrWhiteSpace(_part.Text))
            {
                return ResolveResource("EmptyText");
            }
            else
            { 
                return _part.Text;
            }
        }

        private string ResolveResource(string suffix)
        {
            var res = $"{_part.GetType().Name}_{suffix}";
            var ret = Properties.Resources.ResourceManager.GetString(res);
            if (string.IsNullOrWhiteSpace(ret))
            {
                throw new NotImplementedException($"Missing resource: {res}");
            }
            return ret;
        }
    }
}

View on GitHub (pinned to aa894e51c2)

Solutions

  1. Identify the concrete _part type name (from the thrown message) and add "{TypeName}_PromptText" and "{TypeName}_EmptyText" to Resources.resx and localized resx files.
  2. Enumerate all IPartWithText implementations and confirm each has both keys.
  3. Match the resx key prefix to the exact GetType().Name after any rename.
  4. Rebuild so the resx is recompiled into the assembly.

Example fix

// before: IPartWithText impl 'PromptTextPart' has no strings
// after resx:
//   <data name="PromptTextPart_PromptText"><value>Enter text</value></data>
//   <data name="PromptTextPart_EmptyText"><value>(empty)</value></data>
Defensive patterns

Strategy: validation

Validate before calling

var key = $"{_part.GetType().Name}_{suffix}";
var value = Properties.Resources.ResourceManager.GetString(key);
if (string.IsNullOrWhiteSpace(value)) { Trace.WriteLine($"Missing resource: {key}"); return string.Empty; }

Try / catch

try { return ResolveResource(suffix); } catch (NotImplementedException ex) { Trace.WriteLine(ex); return string.Empty; }

Prevention

When it happens

Trigger: The UI binds PromptText (always evaluated) or calls ToString() when _part.Text is empty, and the concrete part type name lacks the corresponding resx key. The interface IPartWithText hides the real type, so the failure surfaces only at runtime for whichever implementation is active.

Common situations: A new IPartWithText implementer was added without PromptText/EmptyText resx entries; the implementing class was renamed; a localized resx omits the keys.

Related errors


AI-assisted analysis of File-New-Project/EarTrumpet@aa894e51c2 (2026-08-13). Data as JSON: /api/errors/55bad2abdd17d5e4. Report an issue: GitHub.