diff --git a/ConfigParser.cs b/ConfigParser.cs
index aca0b1ff74114438324ad3e4a6f309065002ef9e..2727fb8e70422a1d1c45aebdd115f5de95e7cecc 100644
--- a/ConfigParser.cs
+++ b/ConfigParser.cs
@@ -29,6 +29,11 @@ namespace Config;
 
 abstract class ConfigException: Exception
 {
+	public ConfigParser Parser;
+	internal ConfigException(ConfigParser parser)
+	{
+		Parser = parser;
+	}
 	public override string ToString()
 	{
 		return $"Mistake in config: {ErrorString()}";
@@ -39,7 +44,7 @@ abstract class ConfigDuplicitException: ConfigException
 {
 	public string Name;
 	public int LineA, LineB;
-	public ConfigDuplicitException(string name, int lineA, int lineB)
+	public ConfigDuplicitException(ConfigParser parser, string name, int lineA, int lineB): base(parser)
 	{
 		Name = name;
 		LineA = lineA;
@@ -48,8 +53,8 @@ abstract class ConfigDuplicitException: ConfigException
 }
 class ConfigDuplicitSectionException: ConfigDuplicitException
 {
-	public ConfigDuplicitSectionException(string name, int lineA, int lineB)
-		:base(name, lineA, lineB){}
+	public ConfigDuplicitSectionException(ConfigParser parser, string name, int lineA, int lineB)
+		:base(parser, name, lineA, lineB){}
 	public override string ErrorString()
 	{
 		return $"Duplicit section name {Name} on lines {LineA}, {LineB}";
@@ -57,8 +62,8 @@ class ConfigDuplicitSectionException: ConfigDuplicitException
 }
 class ConfigDuplicitKeyException: ConfigDuplicitException
 {
-	public ConfigDuplicitKeyException(string name, int lineA, int lineB)
-		:base(name, lineA, lineB){}
+	public ConfigDuplicitKeyException(ConfigSection section, string name, int lineA, int lineB)
+		:base(section.Root, name, lineA, lineB){}
 	public override string ErrorString()
 	{
 		return $"Duplicit key name {Name} on lines {LineA}, {LineB}";
@@ -67,7 +72,7 @@ class ConfigDuplicitKeyException: ConfigDuplicitException
 class ConfigNoAmenException: ConfigException
 {
 	public ConfigKeyValue Value;
-	public ConfigNoAmenException(ConfigKeyValue value)
+	public ConfigNoAmenException(ConfigKeyValue value):base(value.Section.Root)
 	{
 		Value = value;
 	}
@@ -80,7 +85,7 @@ class ConfigMixedTabException: ConfigException
 {
 	public ConfigKeyValue Value;
 	public int Line;
-	public ConfigMixedTabException(ConfigKeyValue value, int line)
+	public ConfigMixedTabException(ConfigKeyValue value, int line):base(value.Section.Root)
 	{
 		Value = value;
 		Line = line;
@@ -94,7 +99,7 @@ class ConfigWrongIndentException: ConfigException
 {
 	public ConfigKeyValue? Value;
 	public int Line;
-	public ConfigWrongIndentException(ConfigKeyValue? value, int line)
+	public ConfigWrongIndentException(ConfigSection section, ConfigKeyValue? value, int line):base(section.Root)
 	{
 		Value = value;
 		Line = line;
@@ -109,7 +114,7 @@ class ConfigWrongIndentException: ConfigException
 class ConfigSectionNotDefinedException: ConfigException
 {
 	public string Name;
-	public ConfigSectionNotDefinedException(string name)
+	public ConfigSectionNotDefinedException(ConfigParser parser, string name):base(parser)
 	{
 		Name = name;
 	}
@@ -122,7 +127,7 @@ class ConfigNotDefinedException: ConfigException
 {
 	public ConfigSection Section;
 	public string Name;
-	public ConfigNotDefinedException(ConfigSection section, string name)
+	public ConfigNotDefinedException(ConfigSection section, string name):base(section.Root)
 	{
 		Section = section;
 		Name = name;
@@ -136,7 +141,7 @@ class ConfigNoValueException: ConfigException
 {
 	public ConfigValue Value;
 	public string? Reason;
-	public ConfigNoValueException(ConfigValue value, string? reason=null)
+	public ConfigNoValueException(ConfigValue value, string? reason=null):base(value.Root)
 	{
 		Value = value;
 		Reason = reason;
@@ -149,7 +154,7 @@ class ConfigNoValueException: ConfigException
 class ConfigUnusedOptionException: ConfigException
 {
 	public ConfigKeyValue Value;
-	public ConfigUnusedOptionException(ConfigKeyValue value)
+	public ConfigUnusedOptionException(ConfigKeyValue value):base(value.Root)
 	{
 		Value = value;
 	}
@@ -161,7 +166,7 @@ class ConfigUnusedOptionException: ConfigException
 class ConfigUnusedSectionException: ConfigException
 {
 	public ConfigSection Section;
-	public ConfigUnusedSectionException(ConfigSection section)
+	public ConfigUnusedSectionException(ConfigSection section):base(section.Root)
 	{
 		Section = section;
 	}
@@ -177,7 +182,7 @@ class ConfigParseValueException: ConfigException
 {
 	public ConfigValue Value;
 	public string? Reason;
-	public ConfigParseValueException(ConfigValue value, string? reason=null)
+	public ConfigParseValueException(ConfigValue value, string? reason=null):base(value.Root)
 	{
 		Value = value;
 		Reason = reason;
@@ -192,7 +197,7 @@ class ConfigMistake: ConfigException
 {
 	public ConfigValue Value;
 	public string Text;
-	public ConfigMistake(ConfigValue value, string text)
+	public ConfigMistake(ConfigValue value, string text):base(value.Root)
 	{
 		Value = value;
 		Text = text;
@@ -205,6 +210,7 @@ class ConfigMistake: ConfigException
 
 abstract class ConfigValue
 {
+	public ConfigParser Root;
 	public int Line;
 	internal string? Value;
 	public bool HasText() => Value != null;
@@ -212,6 +218,11 @@ abstract class ConfigValue
 	public virtual string Place{get => $"{Line}: {FullName}";}
 	public abstract string FullName{get;}   // For showing in error
 
+	public ConfigValue(ConfigParser _Root)
+	{
+		Root = _Root;
+	}
+
 	public string AsString()
 	{
 		if(Value == null) throw new ConfigNoValueException(this);
@@ -296,7 +307,7 @@ abstract class ConfigValue
 	}
 	public ConfigParser AsConfig()
 	{
-		return new ConfigParser(AsString(), Line);
+		return new ConfigParser(AsString(), Root.FileName, Line);
 	}
 	public static implicit operator string(ConfigValue v) => v.AsString();
 }
@@ -316,7 +327,7 @@ class ConfigKeyValue: ConfigValue
 	{
 		get => Section.SectionName != null ? $"{Section.SectionName}: {Key}" : Key;
 	}
-	internal ConfigKeyValue(ConfigSection _Section, string _Key, int _line)
+	internal ConfigKeyValue(ConfigSection _Section, string _Key, int _line):base(_Section.Root)
 	{
 		Section = _Section;
 		Key = _Key;
@@ -331,7 +342,7 @@ class ConfigKeyAsValue: ConfigValue
 	{
 		get => (Section.SectionName != null ? $"{Section.SectionName}: " : "") + $"Key {Value}";
 	}
-	internal ConfigKeyAsValue(ConfigKeyValue keyValue)
+	internal ConfigKeyAsValue(ConfigKeyValue keyValue):base(keyValue.Root)
 	{
 		Line = keyValue.Line;
 		Value = keyValue.Key;
@@ -345,7 +356,7 @@ class ConfigSectionNameAsValue: ConfigValue
 	{
 		get => "Section name " + (Section.SectionName != null ? $"\"{Section.SectionName}\"" : "of main section");
 	}
-	internal ConfigSectionNameAsValue(ConfigSection _Section)
+	internal ConfigSectionNameAsValue(ConfigSection _Section):base(_Section.Root)
 	{
 		Section = _Section;
 		Value = Section.SectionName;
@@ -386,7 +397,7 @@ class ConfigSection: IReadOnlyList<ConfigKeyValue>
 	internal void Add(ConfigKeyValue v)
 	{
 		if(valueByName.ContainsKey(v.Key))
-			throw new ConfigDuplicitKeyException(v.Key, v.Line, valueByName[v.Key].Line);
+			throw new ConfigDuplicitKeyException(this, v.Key, v.Line, valueByName[v.Key].Line);
 		valueByName[v.Key] = v;
 		values.Add(v);
 	}
@@ -446,11 +457,13 @@ class ConfigSection: IReadOnlyList<ConfigKeyValue>
 }
 class ConfigParser: IReadOnlyList<ConfigSection>
 {
+	public string? FileName {get; init;}
 	public ConfigSection MainSection;
 	List<ConfigSection> sections = new();
 	Dictionary<string, ConfigSection> sectionByName = new();
-	public ConfigParser(string s, int firstLineIndex = 1)
+	public ConfigParser(string s, string? _FileName = null, int firstLineIndex = 1)
 	{
+		FileName = _FileName;
 		string[] lines = s.Split("\n");
 		var currentSection = MainSection = new(this, null, 0);
 		ConfigKeyValue? lastVal = null;
@@ -468,7 +481,7 @@ class ConfigParser: IReadOnlyList<ConfigSection>
 				currentSection = new ConfigSection(this, tl[1..^1], firstLineIndex + i);
 				if(sectionByName.ContainsKey(currentSection.SectionName))
 				{
-					throw new ConfigDuplicitSectionException(currentSection.SectionName, sectionByName[currentSection.SectionName].Line, firstLineIndex + i);
+					throw new ConfigDuplicitSectionException(this, currentSection.SectionName, sectionByName[currentSection.SectionName].Line, firstLineIndex + i);
 				}
 				sections.Add(currentSection);
 				sectionByName[currentSection.SectionName] = currentSection;
@@ -478,7 +491,7 @@ class ConfigParser: IReadOnlyList<ConfigSection>
 			if(tl[0]==' ' || tl[0]=='\t')
 			{
 				if(lastVal == null)
-					throw new ConfigWrongIndentException(null, firstLineIndex + i);
+					throw new ConfigWrongIndentException(currentSection, null, firstLineIndex + i);
 				if(lastVal.tabs == null)
 				{
 					int spacesLen=0;
@@ -497,7 +510,7 @@ class ConfigParser: IReadOnlyList<ConfigSection>
 				else
 				{
 					if(!tl.StartsWith(lastVal.tabs))
-						throw new ConfigWrongIndentException(lastVal, firstLineIndex + i);
+						throw new ConfigWrongIndentException(currentSection, lastVal, firstLineIndex + i);
 					lastVal.Value += "\n" + tl[lastVal.tabs.Length..];
 				}
 				continue;
@@ -569,7 +582,7 @@ class ConfigParser: IReadOnlyList<ConfigSection>
 	{
 		if(key == null) return MainSection;
 		if(!sectionByName.TryGetValue(key, out var r))
-			throw new ConfigSectionNotDefinedException(key);
+			throw new ConfigSectionNotDefinedException(this, key);
 		return r.Use();
 	}
 	public void CheckUnused()
diff --git a/Program.cs b/Program.cs
index 692bb57de85d63cc1a0769c8bb731c723653daaf..c92a0f5f16382387cedc9979c3117aa6759bda64 100644
--- a/Program.cs
+++ b/Program.cs
@@ -211,22 +211,25 @@ refresh
 		if(configFile == null)
 		{
 			string configText;
+			string? fileName;
 			try
 			{
-				configText = File.ReadAllText(Environment.GetEnvironmentVariable("HOME")+"/.config/i3/i3csstatus.conf");
+				fileName = Environment.GetEnvironmentVariable("HOME")+"/.config/i3/i3csstatus.conf";
+				configText = File.ReadAllText(fileName);
 			}
 			catch(Exception e) when (e is FileNotFoundException || e is DirectoryNotFoundException)
 			{
+				fileName = null;
 				configText = DefaultConfigText;
 			}
-			parseConfigString(configText);
+			parseConfig(new ConfigParser(configText, fileName));
 		}
 		else
-			parseConfigString(File.ReadAllText(configFile.ToString()));
+			parseConfigString(File.ReadAllText(configFile.ToString()), configFile.ToString());
 	}
-	protected void parseConfigString(string configString)
+	protected void parseConfigString(string configString, string? fileName)
 	{
-		parseConfig(new ConfigParser(configString));
+		parseConfig(new ConfigParser(configString, fileName));
 	}
 	virtual protected void parseConfig(ConfigParser p)
 	{