diff --git a/lib/app/base-chips/field-types/cached-value.js b/lib/app/base-chips/field-types/cached-value.js
--- a/lib/app/base-chips/field-types/cached-value.js
+++ b/lib/app/base-chips/field-types/cached-value.js
@@ -56,16 +56,20 @@
 				when,
 				async (context, path, event_params, resource) => {
 					const cache_resource_id = await resource_id_getter(
+						context,
 						path,
 						event_params,
 						resource
 					);
 					return app.run_action(
-						new app.Sealious.SuperContext(),
+						new app.Sealious.SuperContext(context),
 						["collections", collection.name, cache_resource_id],
 						"edit",
 						{
-							[field_name]: await get_value(cache_resource_id),
+							[field_name]: await get_value(
+								context,
+								cache_resource_id
+							),
 						}
 					);
 				}
@@ -123,7 +127,7 @@
 			const cache_value = await this.encode(
 				context,
 				params,
-				await params.get_value(resource.sealious_id)
+				await params.get_value(context, resource.sealious_id)
 			);
 			await app.Datastore.update(
 				collection.name,
@@ -143,8 +147,13 @@
 			),
 		};
 	},
-	decode: function(context, params, { value }) {
-		return this._call_base_method("decode", context, params, value);
+	decode: function(context, params, value_in_db) {
+		return this._call_base_method(
+			"decode",
+			context,
+			params,
+			value_in_db ? value_in_db.value : null
+		);
 	},
 	format: function(context, params, decoded_value, format) {
 		const base_field_type = app.FieldType(params.base_field_type.name);
diff --git a/lib/app/base-chips/field-types/cached-value.subtest.js b/lib/app/base-chips/field-types/cached-value.subtest.js
--- a/lib/app/base-chips/field-types/cached-value.subtest.js
+++ b/lib/app/base-chips/field-types/cached-value.subtest.js
@@ -34,7 +34,7 @@
 								min: 0,
 							},
 						},
-						get_value: async resource_id => {
+						get_value: async (context, resource_id) => {
 							return app.run_action(
 								new app.Sealious.SuperContext(),
 								["collections", "accounts", resource_id],
@@ -90,7 +90,7 @@
 						values: Object.values(action_to_status),
 					},
 				},
-				get_value: async resource_id => {
+				get_value: async (context, resource_id) => {
 					const [latest_action] = await app.Datastore.aggregate(
 						"actions",
 						[
@@ -262,10 +262,20 @@
 
 function make_refresh_on() {
 	return {
-		"post:actions:create": async (path, event_params, resource) => {
+		"post:actions:create": async (
+			context,
+			path,
+			event_params,
+			resource
+		) => {
 			return resource.body.account;
 		},
-		"post:actions\\..*:edit": async (path, event_params, resource) => {
+		"post:actions\\..*:edit": async (
+			context,
+			path,
+			event_params,
+			resource
+		) => {
 			return resource.body.account;
 		},
 	};
diff --git a/lib/app/base-chips/field-types/single_reference.js b/lib/app/base-chips/field-types/single_reference.js
--- a/lib/app/base-chips/field-types/single_reference.js
+++ b/lib/app/base-chips/field-types/single_reference.js
@@ -161,7 +161,7 @@
 							field_name
 					);
 				filter[
-					temp_field_name + ".0." + field_value_path
+					`${temp_field_name}.0.body.${field_name}`
 				] = field.filter_to_query(context, request_filter[field_name]);
 			}
 			return Promise.props(filter).then(function(_filter) {
diff --git a/lib/app/base-chips/field-types/single_reference.subtest.js b/lib/app/base-chips/field-types/single_reference.subtest.js
--- a/lib/app/base-chips/field-types/single_reference.subtest.js
+++ b/lib/app/base-chips/field-types/single_reference.subtest.js
@@ -3,6 +3,10 @@
 const axios = require("axios");
 const { create_resource_as } = locreq("test_utils");
 const { with_running_app } = locreq("test_utils/with-test-app.js");
+const assert_throws_async = locreq("test_utils/assert_throws_async.js");
+const A = "/api/v1/collections/A";
+const B = "/api/v1/collections/B";
+const C = "/api/v1/collections/C";
 
 describe("single_reference", () => {
 	async function create_referencing_collections(app) {
@@ -28,66 +32,129 @@
 	}
 
 	it("should not allow a value that is not an existing id", async () =>
-		with_running_app(async ({ app, base_url }) => {
+		with_running_app(async ({ app, base_url, rest_api }) => {
 			await create_referencing_collections(app);
-			return axios
-				.post(`${base_url}/api/v1/collections/A`, {
-					reference_to_b: "non-existing-id",
-				})
-				.then(res => {
-					throw "This should not succeed";
-				})
-				.catch(res =>
+			await assert_throws_async(
+				() =>
+					rest_api.post(A, {
+						reference_to_b: "non-existing-id",
+					}),
+				e =>
 					assert.equal(
-						res.response.data.data.reference_to_b.message,
+						e.response.data.data.reference_to_b.message,
 						"Nie masz dostępu do danego zasobu z kolekcji B lub on nie istnieje."
 					)
-				);
+			);
 		}));
 
 	it("should allow a value that exists in B", async () =>
-		with_running_app(async ({ app, base_url }) => {
-			create_referencing_collections(app);
-			const b_id = (await axios.post(`${base_url}/api/v1/collections/B`, {
-				number: 1,
-			})).data.id;
-			return axios.post(`${base_url}/api/v1/collections/A`, {
-				reference_to_b: b_id,
+		with_running_app(async ({ app, base_url, rest_api }) => {
+			await create_referencing_collections(app);
+			const { id } = await rest_api.post(B, { number: 1 });
+			await rest_api.post(A, {
+				reference_to_b: id,
 			});
 		}));
 
 	it("should not allow a value that exists in B but does not meet the filter criteria", async () =>
-		with_running_app(async ({ app, base_url }) => {
-			create_referencing_collections(app);
-			const b_id = (await axios.post(`${base_url}/api/v1/collections/B`, {
-				number: 0,
-			})).data.id;
-
-			return axios
-				.post(`${base_url}/api/v1/collections/A`, {
-					filtered_reference_to_b: b_id,
-				})
-				.then(response => {
-					throw "This should fail";
-				})
-				.catch(error => {
+		with_running_app(async ({ app, base_url, rest_api }) => {
+			await create_referencing_collections(app);
+			const { id } = await rest_api.post(B, { number: 0 });
+			await assert_throws_async(
+				() =>
+					rest_api.post(A, {
+						filtered_reference_to_b: id,
+					}),
+				e =>
 					assert.equal(
-						error.response.data.data.filtered_reference_to_b
-							.message,
+						e.response.data.data.filtered_reference_to_b.message,
 						"Nie masz dostępu do danego zasobu z kolekcji B lub on nie istnieje."
-					);
-				});
+					)
+			);
 		}));
 
 	it("should allow a value that exists in B but does not meet the filter criteria", async () =>
-		with_running_app(async ({ app, base_url }) => {
-			create_referencing_collections(app);
-			const b_id = (await axios.post(`${base_url}/api/v1/collections/B`, {
-				number: 1,
-			})).data.id;
+		with_running_app(async ({ app, base_url, rest_api }) => {
+			await create_referencing_collections(app);
+			const { id } = await rest_api.post(B, { number: 1 });
+			await rest_api.post(A, { filtered_reference_to_b: id });
+		}));
+
+	it("should be filterable by referenced collection fields", async () =>
+		with_running_app(async ({ app, base_url, rest_api }) => {
+			await create_referencing_collections(app);
 
-			return axios.post(`${base_url}/api/v1/collections/A`, {
-				filtered_reference_to_b: b_id,
+			for (let number of [1, 2, 3]) {
+				const { id } = await rest_api.post(B, { number });
+				await rest_api.post(A, { reference_to_b: id });
+			}
+
+			const response = await rest_api.get(
+				`${A}?filter[reference_to_b][number]=3&format[reference_to_b]=expand`
+			);
+			assert.deepEqual(response.length, 1);
+			assert.deepEqual(response[0].body.reference_to_b.body.number, 3);
+		}));
+
+	it("should be filterable by referenced collection field of referenced collection field", async () =>
+		with_running_app(async ({ app, base_url, rest_api }) => {
+			// A => B => C
+			await app.createChip(app.Sealious.Collection, {
+				name: "A",
+				fields: [
+					{
+						name: "reference_to_b",
+						type: "single_reference",
+						params: { collection: "B" },
+					},
+				],
 			});
+			await app.createChip(app.Sealious.Collection, {
+				name: "B",
+				fields: [
+					{
+						name: "reference_to_c",
+						type: "single_reference",
+						params: { collection: "C" },
+					},
+				],
+			});
+
+			await app.createChip(app.Sealious.Collection, {
+				name: "C",
+				fields: [
+					{
+						name: "number",
+						type: "int",
+					},
+				],
+			});
+			let c_ids = [];
+			let b_ids = [];
+			for (let number of [1, 2, 3]) {
+				const { id } = await rest_api.post(C, { number });
+				c_ids.push(id);
+			}
+			for (let c_id of c_ids) {
+				const { id } = await rest_api.post(B, {
+					reference_to_c: c_id,
+				});
+				b_ids.push(id);
+			}
+			for (let b_id of b_ids) {
+				const a = await rest_api.post(A, { reference_to_b: b_id });
+			}
+
+			const result = await rest_api
+				.get(
+					`${A}?filter[reference_to_b][reference_to_c][number]=3&format[reference_to_b]=deep-expand:2`
+				)
+				.catch(console.error);
+
+			assert.deepEqual(result.length, 1);
+			assert.deepEqual(
+				result[0].body.reference_to_b.body.reference_to_c.body.number,
+				3
+			);
 		}));
 });
diff --git a/lib/app/event-manager.js b/lib/app/event-manager.js
--- a/lib/app/event-manager.js
+++ b/lib/app/event-manager.js
@@ -20,7 +20,7 @@
 			"post",
 			async (context, path, params, intent) => {
 				const token = (await this.app.run_action(
-					new this.app.Sealious.SuperContext(),
+					new this.app.Sealious.SuperContext(context),
 					["collections", collection_name, intent.id],
 					"show"
 				)).body.token;
diff --git a/lib/app/run-action-curry.js b/lib/app/run-action-curry.js
--- a/lib/app/run-action-curry.js
+++ b/lib/app/run-action-curry.js
@@ -15,9 +15,7 @@
 
 function run_action_curry(app) {
 	return function run_action(context, subject_path, action_name, params) {
-		const original_context = context.is_super
-			? context.original_context
-			: context;
+		const original_context = context.original_context || context;
 
 		if (!ActionResultCache.has(original_context)) {
 			ActionResultCache.set(original_context, new Map());
diff --git a/lib/super-context.js b/lib/super-context.js
--- a/lib/super-context.js
+++ b/lib/super-context.js
@@ -13,6 +13,10 @@
 
 	ret.original_context = regular_context;
 
+	while (ret.original_context.original_context) {
+		ret.original_context = ret.original_context.original_context;
+	}
+
 	return ret;
 }